From 3b8e07e0728eb395ed46286ccab5986c88069e54 Mon Sep 17 00:00:00 2001 From: BSMaidSafe Date: Fri, 27 Feb 2015 17:46:04 +0000 Subject: [PATCH 01/72] FakeVaultFacade WIP. --- .../tests/routing_fake_vault_facade_test.cc | 56 +++++++++++ .../routing/tests/utils/fake_vault_facade.cc | 46 +++++++++ .../routing/tests/utils/fake_vault_facade.h | 99 +++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc create mode 100644 src/maidsafe/routing/tests/utils/fake_vault_facade.cc create mode 100644 src/maidsafe/routing/tests/utils/fake_vault_facade.h diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc new file mode 100644 index 00000000..61b2dade --- /dev/null +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -0,0 +1,56 @@ +/* Copyright 2014 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#include "maidsafe/common/test.h" +#include "maidsafe/routing/tests/utils/fake_vault_facade.h" + +namespace maidsafe { + +namespace routing { + +namespace test { + +TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { + ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); +} + +TEST(RoutingFakeVaultFacadeTest, FUNC_Put) { + std::vector> vaults(3); + unsigned short port(5483); + for (auto& vault : vaults) + vault.second = port++; + for (auto& vault : vaults) + ASSERT_NO_THROW(vault.first.StartAccepting(vault.second)); + + for (size_t i = 0; i != vaults.size(); ++i) { + for (size_t j = 0; j != vaults.size(); ++j) { + if (j > i) { + asio::ip::udp::endpoint endpoint(asio::ip::udp::v4(), vaults[j].second); + vaults[i].first.AddContact(endpoint); + } + } + } + Sleep(std::chrono::seconds(10)); + std::cout << "test end" << std::endl; +} + +} // namespace test + +} // namespace routing + +} // namespace maidsafe diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc new file mode 100644 index 00000000..bb68fe3d --- /dev/null +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -0,0 +1,46 @@ +/* Copyright 2014 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#include "maidsafe/routing/tests/utils/fake_vault_facade.h" + +namespace maidsafe { + +namespace vault { + +namespace test { + +routing::HandleGetReturn FakeVaultFacade::HandleGet(routing::SourceAddress from, + routing::Authority authority, DataTagValue data_type, Identity data_name) { + switch (authority) { + case routing::Authority::nae_manager: + if (data_type == DataTagValue::kImmutableDataValue) + return DataManager::template HandleGet(from, data_name); + else if (data_type == DataTagValue::kMutableDataValue) + return DataManager::template HandleGet(from, data_name); + break; + default: + break; + } + return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); +} + +} // namespace test + +} // namespace vault + +} // namespace maidsafe diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h new file mode 100644 index 00000000..41263d90 --- /dev/null +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -0,0 +1,99 @@ +/* Copyright 2014 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#ifndef MAIDSAFE_ROUTING_TESTS_UTILS_FAKE_VAULT_FACADE_H_ +#define MAIDSAFE_ROUTING_TESTS_UTILS_FAKE_VAULT_FACADE_H_ + +#include "maidsafe/routing/routing_node.h" + +namespace maidsafe { + +namespace vault { + +namespace test { + +template +class DataManager { + public: + DataManager() {} + + template + routing::HandleGetReturn HandleGet(const routing::SourceAddress& from, const Identity& name); + + private: + routing::CloseGroupDifference close_group_; +}; + +template template +routing::HandleGetReturn DataManager::HandleGet( + const routing::SourceAddress& /*from*/, const Identity& /*name*/) { + std::cout << "DataManager::HandleGet called" << std::endl; + return routing::HandleGetReturn(); +} + +// Helper function to parse data name and contents +// FIXME this need discussion, adding it temporarily to progress +template +ParsedType ParseData(const SerialisedData& serialised_data) { + InputVectorStream binary_input_stream{serialised_data}; + typename ParsedType::Name name; + typename ParsedType::serialised_type contents; + Parse(binary_input_stream, name, contents); + return ParsedType(name, contents); +} + +class FakeVaultFacade : public DataManager, + public routing::RoutingNode { + public: + FakeVaultFacade() + : DataManager(), + routing::RoutingNode() {} + + ~FakeVaultFacade() = default; + + enum class FunctorType { FunctionOne, FunctionTwo }; + + void HandleConnectionAdded(routing::Address /*address*/) {} + + routing::HandleGetReturn HandleGet(routing::SourceAddress from, routing::Authority authority, + DataTagValue data_type, Identity data_name); + + routing::HandlePutPostReturn HandlePut(routing::SourceAddress from, + routing::Authority from_authority, routing::Authority authority, DataTagValue data_type, + SerialisedData serialised_data); + + bool HandlePost(const routing::SerialisedMessage& message); + // not in local cache do upper layers have it (called when we are in target group) + template + boost::expected HandleGet(routing::Address) { + return boost::make_unexpected(MakeError(CommonErrors::no_such_element)); + } + // default put is allowed unless prevented by upper layers + bool HandlePut(routing::Address, routing::SerialisedMessage); + // if the implementation allows any put of data in unauthenticated mode + bool HandleUnauthenticatedPut(routing::Address, routing::SerialisedMessage); + void HandleChurn(routing::CloseGroupDifference diff); +}; + +} // namespace test + +} // namespace vault + +} // namespace maidsafe + +#endif // MAIDSAFE_ROUTING_TESTS_UTILS_FAKE_VAULT_FACADE_H_ From c20c89e557510f8beedf4b6f75635ef508981c74 Mon Sep 17 00:00:00 2001 From: prakash Date: Sun, 1 Mar 2015 03:14:55 +0000 Subject: [PATCH 02/72] Restoring routing node and connection manager to old state along with some notes. --- include/maidsafe/routing/routing_node.h | 121 ++++----- src/maidsafe/routing/connection_manager.cc | 238 ++++-------------- src/maidsafe/routing/connection_manager.h | 105 ++------ src/maidsafe/routing/routing_node.cc | 43 ---- ...uting_connection_manager_check_in_group.cc | 50 ++-- .../tests/routing_network_init_test.cc | 22 +- 6 files changed, 165 insertions(+), 414 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index bcb1475a..5f86950b 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -65,6 +65,13 @@ class RoutingNode { RoutingNode& operator=(RoutingNode&&) = delete; ~RoutingNode(); + // normal bootstrap mechanism + template + BootstrapReturn Bootstrap(CompletionToken token); + // used where we wish to pass a specific node to bootstrap from + template + BootstrapReturn Bootstrap(Endpoint endpoint, CompletionToken&& token); + // // will return with the data template GetReturn Get(Identity name, CompletionToken token); @@ -75,21 +82,9 @@ class RoutingNode { template PostReturn Post(Address to, FunctorType functor, CompletionToken token); - void AddBootstrapContact(crux::endpoint /*endpoint*/) { - // bootstrap_handler_.AddBootstrapContact(endpoint); - } - - void AddContact(asio::ip::udp::endpoint endpoint) { - crux_asio_service_.service().post( - [=]() { connection_manager_.AddNode(boost::none, EndpointPair(endpoint)); }); - } - - void StartAccepting(unsigned short port) { - crux_asio_service_.service().post([=]() { connection_manager_.StartAccepting(port); }); - } - - void Shutdown() { - crux_asio_service_.service().post([=]() { connection_manager_.Shutdown(); }); + void AddBootstrapContact(Contact bootstrap_contact) { + bootstrap_handler_.AddBootstrapContacts(std::vector(1, bootstrap_contact)); + // FIXME bootstrap handler may be need to be updated to take one entry always } private: @@ -117,14 +112,13 @@ class RoutingNode { void HandleMessage(routing::Post post, MessageHeader original_header); bool TryCache(MessageTypeTag tag, MessageHeader header, Address name); Authority OurAuthority(const Address& element, const MessageHeader& header) const; - virtual void MessageReceived(NodeId peer_id, SerialisedMessage serialised_message); - // virtual void ConnectionLost(NodeId peer) override final; + void MessageReceived(Address peer_id, SerialisedMessage serialised_message); + void ConnectionLost(Address peer); void OnCloseGroupChanged(CloseGroupDifference close_group_difference); SourceAddress OurSourceAddress() const; SourceAddress OurSourceAddress(GroupAddress) const; - // void OnBootstrap(asio::error_code, rudp::Contact, - // std::function); + void OnBootstrap(asio::error_code, Contact, std::function); template void SendDirect(NodeId, Message, SendHandler); @@ -144,7 +138,7 @@ class RoutingNode { std::atomic message_id_; boost::optional
bootstrap_node_; // This crashes for me (PeterJ) on linux. - // BootstrapHandler bootstrap_handler_; + BootstrapHandler bootstrap_handler_; ConnectionManager connection_manager_; LruCache filter_; Sentinel sentinel_; @@ -152,15 +146,20 @@ class RoutingNode { std::vector
connected_nodes_; }; +// FIXME(Prakash) temporary code. To be replaced by connections::Send() +// Alternatively, All Send go via Connection manager to stop misuse of Send functionality here +template +void Connections_Send(const Address&, const SerialisedMessage&, Handler) {} + template RoutingNode::RoutingNode() : crux_asio_service_(1), asio_service_(4), - our_fob_(passport::Pmid(passport::Anpmid())), + our_fob_(passport::CreatePmidAndSigner().first), message_id_(RandomUint32()), bootstrap_node_(boost::none), - // bootstrap_handler_(), - connection_manager_(crux_asio_service_.service(), passport::PublicPmid(our_fob_)), + bootstrap_handler_(), + connection_manager_(crux_asio_service_.service(), Address(our_fob_.name()->string())), filter_(std::chrono::minutes(20)), sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), @@ -170,10 +169,6 @@ RoutingNode::RoutingNode() cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); // try an connect to any local nodes (5483) Expect to be told Node_Id auto temp_id(Address(RandomString(Address::kSize))); - - connection_manager_.SetOnConnectionAdded( - [=](Address addr) { static_cast(this)->HandleConnectionAdded(addr); }); - // PeterJ: Start listening on ports 5483 and 5433 (why two though?) // rudp_.Add(rudp::Contact(temp_id, EndpointPair{rudp::Endpoint{GetLocalIp(), 5483}, // rudp::Endpoint{GetLocalIp(), 5433}}, @@ -186,7 +181,6 @@ RoutingNode::RoutingNode() // } //}); - // PeterJ: Read endpoints from database and connect to them. // for (auto& node : bootstrap_handler_.ReadBootstrapContacts()) { // rudp_.Add(node, [node, this](asio::error_code error) { // if (!error) { @@ -216,7 +210,7 @@ GetReturn RoutingNode::Get(Identity name, CompletionToke GetData request(DataType::Tag::kValue, name, OurSourceAddress()); auto message(Serialise(our_header, MessageToTag::value(), request)); for (const auto& target : connection_manager_.GetTarget(Address(name.string()))) { - connection_manager_.FindPeer(target)->Send(message, [](asio::error_code) {}); + Connections_Send(target.id, message, [](asio::error_code) {}); // FIXME(Prakash) } }); return result.get(); @@ -240,7 +234,7 @@ PutReturn RoutingNode::Put(Address to, DataType data, // fixme data should serialise properly and not require the above call to serialse() auto message(Serialise(our_header, MessageToTag::value(), request)); for (const auto& target : connection_manager_.GetTarget(to)) { - connection_manager_.FindPeer(target)->Send(message, [](asio::error_code) {}); + Connections_Send(target.id, message, [](asio::error_code) {}); } }); return result.get(); @@ -260,8 +254,7 @@ PostReturn RoutingNode::Post(Address to, FunctorType fun auto message(Serialise(our_header, MessageToTag::value(), request)); for (const auto& target : connection_manager_.GetTarget(to)) { - // FIXME(PeterJ) Call the above handler when all send handlers finish. - connection_manager_.FindPeer(target)->Send(message, [](asio::error_code) {}); + Connections_Send(target.id, message, [](asio::error_code) {}); } }); return result.get(); @@ -273,18 +266,17 @@ void RoutingNode::ConnectToCloseGroup() { MessageHeader header(DestinationAddress(std::make_pair(Destination(OurId()), boost::none)), SourceAddress{OurSourceAddress()}, ++message_id_, Authority::node); if (bootstrap_node_) { - auto peer = connection_manager_.FindPeer(*bootstrap_node_); - peer->Send(Serialise(header, MessageToTag::value(), message), + // this is special case , so probably have special function in connection manager to send to bootstrap node + Connections_Send(*bootstrap_node_, Serialise(header, MessageToTag::value(), message), [](asio::error_code error) { if (error) { - LOG(kWarning) << "rudp cannot send via bootstrap node" << error.message(); + LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); } }); return; } for (const auto& target : connection_manager_.GetTarget(OurId())) { - auto peer = connection_manager_.FindPeer(target); - peer->Send(Serialise(header, MessageToTag::value(), message), + Connections_Send(target.id, Serialise(header, MessageToTag::value(), message), [](asio::error_code error) { if (error) { LOG(kWarning) << "rudp cannot send" << error.message(); @@ -340,8 +332,7 @@ void RoutingNode::MessageReceived(NodeId /* peer_id */, // send to next node(s) even our close group (swarm mode) for (const auto& target : connection_manager_.GetTarget(header.Destination().first)) { - PeerNode* peer = connection_manager_.FindPeer(target); - peer->Send(serialised_message, [](asio::error_code error) { + Connections_Send(target.id, serialised_message, [](asio::error_code error) { if (error) { LOG(kWarning) << "cannot send" << error.message(); } @@ -422,7 +413,7 @@ Authority RoutingNode::OurAuthority(const Address& element, // reply with our details; template void RoutingNode::HandleMessage(Connect connect, MessageHeader original_header) { - if (!connection_manager_.IsManaged(connect.requester_id())) + if (!connection_manager_.SuggestNodeToAdd(connect.requester_id())) return; auto targets(connection_manager_.GetTarget(connect.requester_id())); ConnectResponse respond(connect.requester_endpoints(), NextEndpointPair(), connect.requester_id(), @@ -436,32 +427,30 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h // shutdown // :24/01/2015 for (auto& target : targets) { - connection_manager_.FindPeer(target) - ->Send(Serialise(header, MessageToTag::value(), respond), - [connect, this](asio::error_code error_code) { - if (error_code) - return; - }); + Connections_Send(target.id, Serialise(header, MessageToTag::value(), respond), + [connect, this](asio::error_code error_code) { + if (error_code) + return; + }); } - connection_manager_.AddNode(NodeInfo(connect.requester_id(), connect.requester_fob(), true), - connect.requester_endpoints()); + auto added = connection_manager_.AddNode(NodeInfo(connect.requester_id(), connect.requester_fob(), + true), connect.requester_endpoints()); - // if (added) - // static_cast(this)->HandleChurn(*added); + if (added) + static_cast(this)->HandleChurn(*added); } template void RoutingNode::HandleMessage(ConnectResponse connect_response) { - if (!connection_manager_.IsManaged(connect_response.requester_id())) + if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) return; - - connection_manager_.AddNode( + auto added = connection_manager_.AddNode( NodeInfo(connect_response.requester_id(), connect_response.receiver_fob(), true), connect_response.receiver_endpoints()); - // auto target = connect_response.requester_id(); - // TODO(PeterJ): + auto target = connect_response.requester_id(); + // TODO(Prakash): below may not be required if connecting socket also takes place in connection mgr // rudp_.Add( // rudp::Contact(connect_response.receiver_id(), connect_response.receiver_endpoints(), // connect_response.receiver_fob().public_key()), @@ -470,19 +459,19 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { // this->connection_manager_.DropNode(target); // return; // } - // if (added) - // static_cast(this)->HandleChurn(*added); - // if (connection_manager_.Size() >= QuorumSize) { - // rudp_.Remove(*bootstrap_node_, asio::use_future).get(); - // bootstrap_node_ = boost::none; - // } - // }); + if (added) + static_cast(this)->HandleChurn(*added); + if (connection_manager_.Size() >= QuorumSize) { +// rudp_.Remove(*bootstrap_node_, asio::use_future).get(); // FIXME (Prakash) + bootstrap_node_ = boost::none; + } } + template void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader original_header) { auto group = connection_manager_.OurCloseGroup(); // add ourselves - group.push_back(passport::PublicPmid(our_fob_)); + group.emplace_back(NodeInfo(OurId(), passport::PublicPmid(our_fob_))); FindGroupResponse response(find_group.target_id(), std::move(group)); MessageHeader header(DestinationAddress(original_header.ReturnDestinationAddress()), SourceAddress(OurSourceAddress(GroupAddress(find_group.target_id()))), @@ -490,7 +479,7 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi asymm::Sign(Serialise(response), our_fob_.private_key())); auto message(Serialise(header, MessageToTag::value(), response)); for (const auto& node : connection_manager_.GetTarget(original_header.FromNode())) { - connection_manager_.FindPeer(node)->Send(message, [](asio::error_code) {}); + Connections_Send(node.id, message, [](asio::error_code) {}); } } @@ -502,13 +491,13 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, // through here. for (const auto node_pmid : find_group_reponse.group()) { Address node_id(node_pmid.name()->string()); - if (!connection_manager_.IsManaged(node_id)) + if (!connection_manager_.SuggestNodeToAdd(node_id)) continue; Connect message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); MessageHeader header(DestinationAddress(std::make_pair(Destination(node_id), boost::none)), SourceAddress{OurSourceAddress()}, ++message_id_, Authority::nae_manager); for (const auto& target : connection_manager_.GetTarget(node_id)) - connection_manager_.FindPeer(target)->Send( + Connections_Send( Serialise(header, MessageToTag::value(), message), [](asio::error_code) {}); } } diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 615a7976..1b4edb3c 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -44,208 +44,74 @@ using std::move; using boost::none_t; using boost::optional; -ConnectionManager::ConnectionManager(boost::asio::io_service& ios, PublicPmid our_fob) - : io_service_(ios), - our_fob_(std::move(our_fob)), - our_id_(our_fob_.name()->string()), - peers_(Comparison(our_id_)), - current_close_group_(), - destroy_indicator_(new boost::none_t()) {} - -bool ConnectionManager::IsManaged(const Address& node_id) const { - return peers_.find(node_id) != peers_.end(); - // return routing_table_.CheckNode(node_to_add); +ConnectionManager::ConnectionManager(boost::asio::io_service& ios, Address our_id) + : mutex_(), + io_service_(ios), + routing_table_(our_id), + current_close_group_() {} + +bool ConnectionManager::SuggestNodeToAdd(const Address& node_to_add) const { + return routing_table_.CheckNode(node_to_add); } -std::set ConnectionManager::GetTarget( - const Address& target_node) const { - // TODO(PeterJ): The previous code was quite more complicated, so recheck correctness of this one. - return std::set(Comparison(target_node)); - // for (const auto& peer : peers_) { - // result.insert(peer.first); - //} - // return result; - // auto nodes(routing_table_.TargetNodes(target_node)); - ////nodes.erase(std::remove_if(std::begin(nodes), std::end(nodes), - //// [](NodeInfo& node) { return !node.connected(); }), - //// std::end(nodes)); - // return nodes; +std::vector ConnectionManager::GetTarget(const Address& target_node) const { + auto nodes(routing_table_.TargetNodes(target_node)); + nodes.erase(std::remove_if(std::begin(nodes), std::end(nodes), + [](NodeInfo& node) { return !node.connected; }), + std::end(nodes)); + return nodes; } -// boost::optional ConnectionManager::LostNetworkConnection( -// const Address& node) { -// routing_table_.DropNode(node); -// return GroupChanged(); -//} - -optional ConnectionManager::DropNode(const Address& their_id) { - // routing_table_.DropNode(their_id); - peers_.erase(their_id); + boost::optional ConnectionManager::LostNetworkConnection( + const Address& node) { + routing_table_.DropNode(node); return GroupChanged(); } -// acceptor_(io_service_, crux::endpoint(boost::asio::ip::udp::v4(), 5483)), -void ConnectionManager::StartAccepting(unsigned short port) { - auto acceptor_i = acceptors_.find(port); - - if (acceptor_i == acceptors_.end()) { - crux::endpoint endpoint(boost::asio::ip::udp::v4(), port); - auto acceptor = std::unique_ptr(new crux::acceptor(io_service_, endpoint)); - auto pair = acceptors_.insert(std::make_pair(port, std::move(acceptor))); - acceptor_i = pair.first; - } - - auto socket = make_shared(io_service_); - - auto& acceptor = acceptor_i->second; - - weak_ptr destroy_guard = destroy_indicator_; - - acceptor->async_accept(*socket, [=](boost::system::error_code error) { - if (!destroy_guard.lock()) - return; - - if (error) { - if (error == boost::asio::error::operation_aborted) { - return; - } - } - - StartAccepting(port); - - AsyncExchange(*socket, Serialise(our_fob_.name(), our_fob_.Serialise()), - [=](boost::system::error_code error, SerialisedMessage data) { - if (!destroy_guard.lock()) - return; - - if (error) - return; - - InputVectorStream data_stream(std::move(data)); - PublicPmid::Name their_pmid_name; - PublicPmid::serialised_type their_pmid_value; - Parse(data_stream, their_pmid_name, their_pmid_value); - NodeInfo their_node_info(Address(their_pmid_name->string()), - PublicPmid(their_pmid_name, their_pmid_value), true); - InsertPeer(PeerNode(std::move(their_node_info), std::move(socket))); - }); - }); +optional ConnectionManager::DropNode(const Address& their_id) { + routing_table_.DropNode(their_id); + // FIXME(Prakash) remove connection ? + return GroupChanged(); } -void ConnectionManager::AddNode(optional assumed_node_info, EndpointPair eps) { - static const crux::endpoint unspecified_ep(boost::asio::ip::udp::v4(), 0); - - // TODO(PeterJ): Try the internal endpoint as well - auto endpoint = convert::ToBoost(eps.external); - - auto pair_i = being_connected_.find(endpoint); - - if (pair_i == being_connected_.end()) { - bool inserted = false; - auto socket = make_shared(io_service_, unspecified_ep); - std::tie(pair_i, inserted) = being_connected_.insert(std::make_pair(endpoint, socket)); - } - - auto socket = pair_i->second; - weak_ptr weak_socket = socket; - - socket->async_connect(convert::ToBoost(eps.external), [=](boost::system::error_code error) { - auto socket = weak_socket.lock(); - - if (!socket) - return; - - if (error) { - being_connected_.erase(endpoint); - return; - } - - AsyncExchange(*socket, Serialise(our_fob_.name(), our_fob_.Serialise()), - [=](boost::system::error_code error, SerialisedMessage data) { - auto socket = weak_socket.lock(); - - if (!socket) - return; - - being_connected_.erase(endpoint); - - if (error) - return; - - InputVectorStream data_stream(std::move(data)); - PublicPmid::Name their_pmid_name; - PublicPmid::serialised_type their_pmid_value; - Parse(data_stream, their_pmid_name, their_pmid_value); - NodeInfo their_node_info(Address(their_pmid_name->string()), - PublicPmid(their_pmid_name, their_pmid_value), true); - - if (assumed_node_info && *assumed_node_info != their_node_info) - return; - - InsertPeer(PeerNode(std::move(their_node_info), std::move(socket))); - }); - }); +boost::optional ConnectionManager::AddNode( + NodeInfo /*node_to_add*/, EndpointPair /*their_endpoint_pair*/) { // FIXME(Prakash) +// rudp::Contact rudp_contact(node_to_add.id, std::move(their_endpoint_pair), +// node_to_add.dht_fob.public_key()); +// asio::spawn(io_service_, [=](asio::yield_context yield) { +// asio::error_code error; +// rudp_.Add(std::move(rudp_contact), yield[error]); + +// if (!error) { +// auto added = routing_table_.AddNode(node_to_add); +// if (!added.first) { +// rudp_.Remove(node_to_add.id, asio::use_future); // become invalid for us +// } else if (added.second) { +// rudp_.Remove(added.second->id, asio::use_future); // a sacrificlal node was found +// } +// } +// }); + return GroupChanged(); } -void ConnectionManager::InsertPeer(PeerNode&& node_arg) { - const auto& id = node_arg.id(); - const auto pair = peers_.insert(std::make_pair(id, std::move(node_arg))); - - if (!pair.second /* = inserted */) { - return; - } - - auto& node = pair.first->second; - - StartReceiving(node); +bool ConnectionManager::CloseGroupMember(const Address& their_id) { + auto close_group(routing_table_.OurCloseGroup()); + return std::any_of(std::begin(close_group), std::end(close_group), + [&their_id](const NodeInfo& node) { return node.id == their_id; }); - if (on_connection_added_) { - on_connection_added_(node.id()); - } -} - -void ConnectionManager::StartReceiving(PeerNode& node) { - auto node_guard = node.DestroyGuard(); - - node.Receive([=, &node](asio::error_code error, const SerialisedMessage& bytes) { - if (!node_guard.lock()) - return; - if (error) - return; - if (!on_receive_) - return; - // Complex handler invocation to be safe in cases where the - // handler destroys this object or in case where the handler - // invocation resets the handler to something else. - auto h = move(on_receive_); - h(node.id(), bytes); - if (!node_guard.lock()) - return; - if (!on_receive_) { - on_receive_ = move(h); - } - StartReceiving(node); - }); } -// bool ConnectionManager::CloseGroupMember(const Address& their_id) { -// auto close_group(routing_table_.OurCloseGroup()); -// return std::any_of(std::begin(close_group), std::end(close_group), -// [&their_id](const NodeInfo& node) { return node.id == their_id; }); -//} - -optional ConnectionManager::GroupChanged() { - auto new_group(OurCloseGroup()); - std::vector
new_group_ids; - for (const auto& group_member_public_pmid : new_group) - new_group_ids.push_back(Address(group_member_public_pmid.name()->string())); - - if (new_group_ids != current_close_group_) { - auto changed = std::make_pair(new_group_ids, current_close_group_); - current_close_group_ = new_group_ids; +boost::optional ConnectionManager::GroupChanged() { + auto new_nodeinfo_group(routing_table_.OurCloseGroup()); + std::vector
new_group; + for (const auto& nodes : new_nodeinfo_group) + new_group.push_back(nodes.id); + std::lock_guard lock(mutex_); + if (new_group != current_close_group_) { + auto changed = std::make_pair(new_group, current_close_group_); + current_close_group_ = new_group; return changed; } - return boost::none; } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 6cceb8bc..6d7c763a 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -60,20 +60,8 @@ namespace routing { class ConnectionManager { using PublicPmid = passport::PublicPmid; - class Comparison { - public: - explicit Comparison(Address our_id) : our_id_(std::move(our_id)) {} - - bool operator()(const Address& lhs, const Address& rhs) const { - return Address::CloserToTarget(lhs, rhs, our_id_); - } - - private: - const Address our_id_; - }; - public: - ConnectionManager(boost::asio::io_service& ios, PublicPmid our_fob); + ConnectionManager(boost::asio::io_service& ios, Address our_id); ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; @@ -81,95 +69,46 @@ class ConnectionManager { ConnectionManager& operator=(const ConnectionManager&) = delete; ConnectionManager& operator=(ConnectionManager&&) = delete; - bool IsManaged(const Address& node_to_add) const; - std::set GetTarget(const Address& target_node) const; - //boost::optional LostNetworkConnection(const Address& node); + bool SuggestNodeToAdd(const Address& node_to_add) const; + std::vector GetTarget(const Address& target_node) const; + boost::optional LostNetworkConnection(const Address& node); + // routing wishes to drop a specific node (may be a node we cannot connect to) boost::optional DropNode(const Address& their_id); - void AddNode(boost::optional node_to_add, EndpointPair); - - std::vector OurCloseGroup() const { - std::vector result; - result.reserve(GroupSize); - size_t i = 0; - for (const auto& pair : peers_) { - if (++i > GroupSize) - break; - result.push_back(pair.second.node_info().dht_fob); - } - return result; - } + boost::optional AddNode(NodeInfo node_to_add, + EndpointPair their_endpoint_pair); + std::vector OurCloseGroup() const { return routing_table_.OurCloseGroup(); } - //size_t CloseGroupBucketDistance() const { - // return routing_table_.BucketIndex(routing_table_.OurCloseGroup().back().id); - //} + size_t CloseGroupBucketDistance() const { + return routing_table_.BucketIndex(routing_table_.OurCloseGroup().back().id); + } bool AddressInCloseGroupRange(const Address& address) const { - if (peers_.size() < GroupSize) + if (routing_table_.Size() < GroupSize) { return true; - return (static_cast(std::distance(peers_.begin(), peers_.upper_bound(address))) < - GroupSize); + } + return NodeId::CloserToTarget(address, routing_table_.OurCloseGroup().back().id, + routing_table_.OurId()); } - const Address& OurId() const { return our_id_; } + const Address& OurId() const { return routing_table_.OurId(); } boost::optional GetPublicKey(const Address& node) const { - auto found_i = peers_.find(node); - if (found_i == peers_.end()) { return boost::none; } - return found_i->second.node_info().dht_fob.public_key(); - } - - //bool CloseGroupMember(const Address& their_id); - - uint32_t Size() { return static_cast(peers_.size()); } - - PeerNode* FindPeer(Address addr) { - auto i = peers_.find(addr); - if (i == peers_.end()) - return nullptr; - return &i->second; - } - - void StartAccepting(unsigned short port); - - template - void SetOnConnectionAdded(Handler handler) { - on_connection_added_ = std::move(handler); + return routing_table_.GetPublicKey(node); } - template - void SetOnReceive(Handler handler) { - on_receive_ = std::move(handler); - } + bool CloseGroupMember(const Address& their_id); - void Shutdown() { - acceptors_.clear(); - being_connected_.clear(); - peers_.clear(); - } + uint32_t Size() { return routing_table_.Size(); } private: boost::optional GroupChanged(); - void InsertPeer(PeerNode&&); - std::weak_ptr DestroyGuard() { return destroy_indicator_; } - void StartReceiving(PeerNode&); - private: + std::mutex mutex_; boost::asio::io_service& io_service_; - - std::function on_connection_added_; - std::function on_receive_; - - PublicPmid our_fob_; - NodeId our_id_; - - std::map> acceptors_; - std::map> being_connected_; - std::map peers_; - + RoutingTable routing_table_; std::vector
current_close_group_; - - std::shared_ptr destroy_indicator_; + std::function group_changed_functor_; }; } // namespace routing diff --git a/src/maidsafe/routing/routing_node.cc b/src/maidsafe/routing/routing_node.cc index 75902eb1..fc801445 100644 --- a/src/maidsafe/routing/routing_node.cc +++ b/src/maidsafe/routing/routing_node.cc @@ -35,49 +35,6 @@ namespace maidsafe { namespace routing { // -// RoutingNode::RoutingNode(asio::io_service& io_service, boost::filesystem::path db_location, -// const passport::Pmid& pmid, std::shared_ptr listener_ptr) -// : io_service_(io_service), -// our_fob_(pmid), -// bootstrap_node_(boost::none), -// rudp_(), -// bootstrap_handler_(std::move(db_location)), -// connection_manager_(io_service, rudp_, Address(pmid.name()->string())), -// listener_ptr_(listener_ptr), -// filter_(std::chrono::minutes(20)), -// sentinel_(io_service_), -// cache_(std::chrono::minutes(60)) { -// // store this to allow other nodes to get our ID on startup. IF they have full routing tables -// they -// // need Quorum number of these signed anyway. -// cache_.Add(Address(pmid.name()->string()), Serialise(passport::PublicPmid(our_fob_))); -// // try an connect to any local nodes (5483) Expect to be told Node_Id -// auto temp_id(Address(RandomString(Address::kSize))); -// rudp_.Add(rudp::Contact(temp_id, rudp::EndpointPair{rudp::Endpoint{GetLocalIp(), 5483}, -// rudp::Endpoint{GetLocalIp(), 5433}}, -// our_fob_.public_key()), -// [this, temp_id](asio::error_code error) { -// if (!error) { -// bootstrap_node_ = temp_id; -// ConnectToCloseGroup(); -// return; -// } -// }); -// for (auto& node : bootstrap_handler_.ReadBootstrapContacts()) { -// rudp_.Add(node, [node, this](asio::error_code error) { -// if (!error) { -// bootstrap_node_ = node.id; -// ConnectToCloseGroup(); -// return; -// } -// }); -// if (bootstrap_node_) -// break; -// } -// } -// -// RoutingNode::~RoutingNode() {} -// // void RoutingNode::ConnectToCloseGroup() { // FindGroup message(NodeAddress(OurId()), OurId()); // MessageHeader header(DestinationAddress(std::make_pair(Destination(OurId()), boost::none)), diff --git a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc index 3756969b..9a0f0675 100644 --- a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc +++ b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc @@ -37,31 +37,31 @@ namespace routing { namespace test { TEST(ConnectionManagerTest, FUNC_AddNodesCheckCloseGroup) { - boost::asio::io_service io_service; - passport::PublicPmid our_public_pmid(passport::CreatePmidAndSigner().first); - auto our_id(Address(our_public_pmid.name()->string())); - ConnectionManager connection_manager(io_service, our_public_pmid); - asymm::Keys key(asymm::GenerateKeyPair()); - std::vector
addresses(60, Address(RandomString(Address::kSize))); - // iterate and fill routing table - auto fob(PublicFob()); - for (auto& node : addresses) { - NodeInfo nodeinfo_to_add(node, fob, true); - EXPECT_TRUE(connection_manager.IsManaged(nodeinfo_to_add.id)); - EndpointPair endpoint_pair; - endpoint_pair.local = (GetRandomEndpoint()); - endpoint_pair.external = (GetRandomEndpoint()); - connection_manager.AddNode(nodeinfo_to_add, endpoint_pair); - } - std::sort(std::begin(addresses), std::end(addresses), - [our_id](const Address& lhs, - const Address& rhs) { return Address::CloserToTarget(lhs, rhs, our_id); }); - auto close_group(connection_manager.OurCloseGroup()); - // no node added as rudp will refuse these connections; - EXPECT_EQ(0U, close_group.size()); - // EXPECT_EQ(GroupSize, close_group.size()); - // for (size_t i(0); i < GroupSize; ++i) - // EXPECT_EQ(addresses.at(i), close_group.at(i).id); +// boost::asio::io_service io_service; +// passport::PublicPmid our_public_pmid(passport::CreatePmidAndSigner().first); +// auto our_id(Address(our_public_pmid.name()->string())); +// ConnectionManager connection_manager(io_service, our_public_pmid); +// asymm::Keys key(asymm::GenerateKeyPair()); +// std::vector
addresses(60, Address(RandomString(Address::kSize))); +// // iterate and fill routing table +// auto fob(PublicFob()); +// for (auto& node : addresses) { +// NodeInfo nodeinfo_to_add(node, fob, true); +// EXPECT_TRUE(connection_manager.IsManaged(nodeinfo_to_add.id)); +// EndpointPair endpoint_pair; +// endpoint_pair.local = (GetRandomEndpoint()); +// endpoint_pair.external = (GetRandomEndpoint()); +// connection_manager.AddNode(nodeinfo_to_add, endpoint_pair); +// } +// std::sort(std::begin(addresses), std::end(addresses), +// [our_id](const Address& lhs, +// const Address& rhs) { return Address::CloserToTarget(lhs, rhs, our_id); }); +// auto close_group(connection_manager.OurCloseGroup()); +// // no node added as rudp will refuse these connections; +// EXPECT_EQ(0U, close_group.size()); +// // EXPECT_EQ(GroupSize, close_group.size()); +// // for (size_t i(0); i < GroupSize; ++i) +// // EXPECT_EQ(addresses.at(i), close_group.at(i).id); } } // namespace test diff --git a/src/maidsafe/routing/tests/routing_network_init_test.cc b/src/maidsafe/routing/tests/routing_network_init_test.cc index 84fc4b6b..8678f8ad 100644 --- a/src/maidsafe/routing/tests/routing_network_init_test.cc +++ b/src/maidsafe/routing/tests/routing_network_init_test.cc @@ -43,20 +43,20 @@ namespace routing { namespace test { TEST(NetworkInitTest, FUNC_TwoNodes) { - struct Node : public RoutingNode { - void HandleMessage(GetData, MessageHeader) {} - void HandleConnectionAdded(NodeId) { - Shutdown(); - } - }; +// struct Node : public RoutingNode { +// void HandleMessage(GetData, MessageHeader) {} +// void HandleConnectionAdded(NodeId) { +// Shutdown(); +// } +// }; - Node n1; - Node n2; +// Node n1; +// Node n2; - unsigned short port = 8080; +// unsigned short port = 8080; - n1.StartAccepting(port); - n2.AddContact(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port)); +// n1.StartAccepting(port); +// n2.AddContact(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port)); } From fb515472b677a326d4b6c56c3d3f89232336c2c5 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 2 Mar 2015 14:10:27 +0000 Subject: [PATCH 03/72] updated comments --- include/maidsafe/routing/routing_node.h | 1 - src/maidsafe/routing/routing_table.h | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 5f86950b..3e5585e5 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -137,7 +137,6 @@ class RoutingNode { passport::Pmid our_fob_; std::atomic message_id_; boost::optional
bootstrap_node_; - // This crashes for me (PeterJ) on linux. BootstrapHandler bootstrap_handler_; ConnectionManager connection_manager_; LruCache filter_; diff --git a/src/maidsafe/routing/routing_table.h b/src/maidsafe/routing/routing_table.h index f3a45458..a79975dc 100644 --- a/src/maidsafe/routing/routing_table.h +++ b/src/maidsafe/routing/routing_table.h @@ -37,6 +37,7 @@ namespace routing { struct NodeInfo; +// N:B Bucket 512 is OurId() and Bucket 0 is the furthest bucket. // The RoutingTable class is used to maintain a list of contacts to which we are connected. It is // threadsafe and all public functions offer the strong exception guarantee. Any public function // having an Address or NodeInfo arg will throw if NDEBUG is defined and the passed ID is invalid. @@ -62,8 +63,10 @@ class RoutingTable { // // 1 - if the contact is ourself, or doesn't have a valid public key, or is already in the table, // it will not be added - // 2 - if the routing table is not full (size < OptimalSize()), the contact will be added - // 3 - if the contact is within our close group, it will be added + // 2 - if the routing table is not full (size < OptimalSize()), the contact will be added with no + // nodes removed + // 3 - if the contact is within our close group, it will be added & possibly a node will be + // removed // 4 - if we can find a candidate for removal (a contact in a bucket with more than 'BucketSize()' // contacts, which is also not within our close group), and if the new contact will fit in a // bucket closer to our own bucket, then we add the new contact. From db79752cf882472f16c097b4f92a8d144a84d2e3 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 2 Mar 2015 14:33:59 +0000 Subject: [PATCH 04/72] style fixes --- include/maidsafe/routing/routing_node.h | 23 +++++++++++----------- src/maidsafe/routing/connection_manager.cc | 5 ++--- src/maidsafe/routing/sentinel.cc | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 3e5585e5..f03973e4 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -65,12 +65,12 @@ class RoutingNode { RoutingNode& operator=(RoutingNode&&) = delete; ~RoutingNode(); - // normal bootstrap mechanism - template - BootstrapReturn Bootstrap(CompletionToken token); - // used where we wish to pass a specific node to bootstrap from - template - BootstrapReturn Bootstrap(Endpoint endpoint, CompletionToken&& token); + // normal bootstrap mechanism + template + BootstrapReturn Bootstrap(CompletionToken token); + // used where we wish to pass a specific node to bootstrap from + template + BootstrapReturn Bootstrap(Endpoint endpoint, CompletionToken&& token); // // will return with the data template @@ -178,7 +178,7 @@ RoutingNode::RoutingNode() // ConnectToCloseGroup(); // return; // } - //}); + // }); // for (auto& node : bootstrap_handler_.ReadBootstrapContacts()) { // rudp_.Add(node, [node, this](asio::error_code error) { @@ -190,7 +190,7 @@ RoutingNode::RoutingNode() // }); // if (bootstrap_node_) // break; - //} + // } } template @@ -265,7 +265,8 @@ void RoutingNode::ConnectToCloseGroup() { MessageHeader header(DestinationAddress(std::make_pair(Destination(OurId()), boost::none)), SourceAddress{OurSourceAddress()}, ++message_id_, Authority::node); if (bootstrap_node_) { - // this is special case , so probably have special function in connection manager to send to bootstrap node + // this is special case , so probably have special function in connection manager to send to + // bootstrap node Connections_Send(*bootstrap_node_, Serialise(header, MessageToTag::value(), message), [](asio::error_code error) { if (error) { @@ -407,7 +408,7 @@ Authority RoutingNode::OurAuthority(const Address& element, // template // void RoutingNode::ConnectionLost(NodeId peer) { // connection_manager_.LostNetworkConnection(peer); -//} +// } // reply with our details; template @@ -449,7 +450,7 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { connect_response.receiver_endpoints()); auto target = connect_response.requester_id(); - // TODO(Prakash): below may not be required if connecting socket also takes place in connection mgr + // TODO(Prakash): below may not be reqd if connecting socket also takes place in connection mgr // rudp_.Add( // rudp::Contact(connect_response.receiver_id(), connect_response.receiver_endpoints(), // connect_response.receiver_fob().public_key()), diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 1b4edb3c..c158fd50 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -62,7 +62,7 @@ std::vector ConnectionManager::GetTarget(const Address& target_node) c return nodes; } - boost::optional ConnectionManager::LostNetworkConnection( +boost::optional ConnectionManager::LostNetworkConnection( const Address& node) { routing_table_.DropNode(node); return GroupChanged(); @@ -75,7 +75,7 @@ optional ConnectionManager::DropNode(const Address& their_ } boost::optional ConnectionManager::AddNode( - NodeInfo /*node_to_add*/, EndpointPair /*their_endpoint_pair*/) { // FIXME(Prakash) + NodeInfo /*node_to_add*/, EndpointPair /*their_endpoint_pair*/) { // FIXME(Prakash) // rudp::Contact rudp_contact(node_to_add.id, std::move(their_endpoint_pair), // node_to_add.dht_fob.public_key()); // asio::spawn(io_service_, [=](asio::yield_context yield) { @@ -98,7 +98,6 @@ bool ConnectionManager::CloseGroupMember(const Address& their_id) { auto close_group(routing_table_.OurCloseGroup()); return std::any_of(std::begin(close_group), std::end(close_group), [&their_id](const NodeInfo& node) { return node.id == their_id; }); - } boost::optional ConnectionManager::GroupChanged() { diff --git a/src/maidsafe/routing/sentinel.cc b/src/maidsafe/routing/sentinel.cc index 853048eb..d961ac90 100644 --- a/src/maidsafe/routing/sentinel.cc +++ b/src/maidsafe/routing/sentinel.cc @@ -43,7 +43,8 @@ boost::optional> Sentinel::Add(MessageHeader h } if (node_key_accumulator_.HaveName(header.FromNode())) { // ok direct - } else if (header.FromGroup() && group_key_accumulator_.HaveName(*header.FromGroup())) { // ok dht + } else if (header.FromGroup() && group_key_accumulator_.HaveName(*header.FromGroup())) { + // ok dht } return boost::none; } From a695457f4e0e97fbab06419e312fc17241270695 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Mon, 2 Mar 2015 17:13:25 +0100 Subject: [PATCH 05/72] Brings the Connections class into this branch --- src/maidsafe/routing/async_exchange.h | 2 +- src/maidsafe/routing/async_queue.h | 129 ++++++++ src/maidsafe/routing/connections.h | 295 ++++++++++++++++++ .../routing/tests/routing_connections_test.cc | 87 ++++++ 4 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 src/maidsafe/routing/async_queue.h create mode 100644 src/maidsafe/routing/connections.h create mode 100644 src/maidsafe/routing/tests/routing_connections_test.cc diff --git a/src/maidsafe/routing/async_exchange.h b/src/maidsafe/routing/async_exchange.h index 92e6b0c8..1fe159a3 100644 --- a/src/maidsafe/routing/async_exchange.h +++ b/src/maidsafe/routing/async_exchange.h @@ -1,4 +1,4 @@ -/* Copyright 2012 MaidSafe.net limited +/* Copyright 2015 MaidSafe.net limited This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which diff --git a/src/maidsafe/routing/async_queue.h b/src/maidsafe/routing/async_queue.h new file mode 100644 index 00000000..dc50bbe6 --- /dev/null +++ b/src/maidsafe/routing/async_queue.h @@ -0,0 +1,129 @@ +/* Copyright 2015 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#ifndef MAIDSAFE_ROUTING_ASYNC_QUEUE_H_ +#define MAIDSAFE_ROUTING_ASYNC_QUEUE_H_ + +#include +#include +#include + +#include "asio/async_result.hpp" + +#include "maidsafe/common/config.h" + +namespace maidsafe { + +namespace routing { + +namespace detail { + +namespace helper { + +template +struct Index {}; + +template +struct GeneratedSequence : GeneratedSequence {}; + +template +struct GeneratedSequence<0, Is...> : Index {}; + +} // namespace helper + +template +inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup, + helper::Index) + -> decltype(f(std::get(tup)...)) { + return f(std::get(tup)...); +} + +template +inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup) + -> decltype(ApplyTuple(f, tup, helper::GeneratedSequence{})) { + return ApplyTuple(std::forward(f), tup, helper::GeneratedSequence{}); +} + +} // namespace detail + +template +class AsyncQueue { + private: + using Handler = std::function; + using Tuple = std::tuple; + + public: + template + void Push(Params&&... args) { + Handler handler; + + { + std::lock_guard lock(mutex); + + if (handlers.empty()) { + return values.emplace(std::forward(args)...); + } + + handler = std::move(handlers.front()); + handlers.pop(); + } + + handler(std::forward(args)...); + } + + template + typename asio::async_result::type, void(Args...)>::type>::type + AsyncPop(CompletionToken&& token) { + using AsioHandler = typename asio::handler_type::type, + void(Args...)>::type; + + AsioHandler handler = std::forward(token); + + asio::async_result result(handler); + + Tuple tuple; + + { + std::lock_guard lock(mutex); + + if (values.empty()) { + handlers.emplace(std::move(handler)); + return result.get(); + } + + tuple = std::move(values.front()); + values.pop(); + } + + detail::ApplyTuple(std::move(handler), tuple); + + return result.get(); + } + + private: + std::mutex mutex; + std::queue handlers; + std::queue values; +}; + +} // namespace routing + +} // namespace maidsafe + +#endif // MAIDSAFE_ROUTING_ASYNC_QUEUE_H_ diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h new file mode 100644 index 00000000..60c146c7 --- /dev/null +++ b/src/maidsafe/routing/connections.h @@ -0,0 +1,295 @@ +/* Copyright 2015 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#ifndef MAIDSAFE_ROUTING_CONNECTIONS_H_ +#define MAIDSAFE_ROUTING_CONNECTIONS_H_ + +#include +#include +#include +#include + +#include "asio/io_service.hpp" +#include "boost/optional.hpp" + +#include "maidsafe/common/asio_service.h" +#include "maidsafe/common/convert.h" +#include "maidsafe/crux/acceptor.hpp" +#include "maidsafe/crux/socket.hpp" + +#include "maidsafe/routing/async_queue.h" +#include "maidsafe/routing/async_exchange.h" +#include "maidsafe/routing/types.h" + +namespace maidsafe { + +namespace routing { + +class Connections { + public: + Connections(boost::asio::io_service&, const Address& our_node_id); + + Connections() = delete; + Connections(const Connections&) = delete; + Connections(Connections&&) = delete; + + Connections& operator=(const Connections&) = delete; + Connections& operator=(Connections&&) = delete; + + ~Connections(); + + template + void Send(const Address&, const SerialisedMessage&, Handler); + + template + void Receive(Handler); + + template + void Connect(asio::ip::udp::endpoint, Handler); + + template + void Accept(unsigned short port, const Handler); + + void Drop(const Address& their_id); + + void Shutdown(); + + const Address& OurId() const { return our_id_; } + + std::size_t max_message_size() const { return 1048576; } + + boost::asio::io_service& get_io_service(); + + private: + void StartReceiving(const Address&, const crux::endpoint&, const std::shared_ptr&); + + boost::asio::io_service& service_; + + Address our_id_; + + std::function on_receive_; + std::function on_drop_; + + std::map> acceptors_; // NOLINT + std::map> connections_; + std::map id_to_endpoint_map_; + + AsyncQueue receive_queue_; +}; + +inline Connections::Connections(boost::asio::io_service& ios, const Address& our_node_id) + : service_(ios), our_id_(our_node_id) {} + +template +void Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, Handler handler) { + service_.post([=]() { + auto remote_endpoint_i = id_to_endpoint_map_.find(remote_id); + + if (remote_endpoint_i == id_to_endpoint_map_.end()) { + return handler(asio::error::bad_descriptor); + } + + auto remote_endpoint = remote_endpoint_i->second; + auto socket_i = connections_.find(remote_endpoint); + assert(socket_i != connections_.end()); + + auto& socket = socket_i->second; + auto buffer = std::make_shared(std::move(bytes)); + + std::weak_ptr weak_socket = socket; + + socket->async_send(boost::asio::buffer(*buffer), + [=](boost::system::error_code error, std::size_t) { + static_cast(buffer); + + if (!weak_socket.lock()) { + return handler(asio::error::operation_aborted); + } + if (error) { + id_to_endpoint_map_.erase(remote_id); + connections_.erase(remote_endpoint); + } + handler(convert::ToStd(error)); + }); + }); +} + +template +void Connections::Receive(Handler handler) { + service_.post([=]() { receive_queue_.AsyncPop(std::move(handler)); }); +} + +inline Connections::~Connections() { Shutdown(); } + +template +void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { + service_.post([=]() { + crux::endpoint unspecified_ep(boost::asio::ip::udp::v4(), 0); + auto socket = std::make_shared(service_, unspecified_ep); + + auto insert_result = connections_.insert(std::make_pair(convert::ToBoost(endpoint), socket)); + + if (!insert_result.second) { + return handler(asio::error::already_started, Address()); + } + + std::weak_ptr weak_socket = socket; + + socket->async_connect(convert::ToBoost(endpoint), [=](boost::system::error_code error) { + auto socket = weak_socket.lock(); + + if (!socket) { + return handler(asio::error::operation_aborted, Address()); + } + if (error) { + return handler(convert::ToStd(error), Address()); + } + + auto remote_endpoint = socket->remote_endpoint(); + + connections_[remote_endpoint] = socket; + + AsyncExchange(*socket, Serialise(our_id_), + [=](boost::system::error_code error, SerialisedMessage data) { + auto socket = weak_socket.lock(); + + if (!socket) { + return handler(asio::error::operation_aborted, Address()); + } + + if (error) { + connections_.erase(remote_endpoint); + return handler(convert::ToStd(error), Address()); + } + + InputVectorStream stream(data); + Address his_id; + Parse(stream, his_id); + + id_to_endpoint_map_[his_id] = remote_endpoint; + StartReceiving(his_id, remote_endpoint, socket); + + handler(convert::ToStd(error), his_id); + }); + }); + }); +} + +template +void Connections::Accept(unsigned short port, const Handler handler) { + service_.post([=]() { + auto find_result = acceptors_.insert(std::make_pair(port, std::shared_ptr())); + + auto& acceptor = find_result.first->second; + + if (!acceptor) { + crux::endpoint endpoint(boost::asio::ip::udp::v4(), port); + acceptor.reset(new crux::acceptor(service_, endpoint)); + } + + std::weak_ptr weak_acceptor = acceptor; + + auto socket = std::make_shared(service_); + + acceptor->async_accept(*socket, [=](boost::system::error_code error) { + if (!weak_acceptor.lock()) { + return handler(asio::error::operation_aborted, asio::ip::udp::endpoint(), Address()); + } + + if (error) { + return handler(asio::error::operation_aborted, asio::ip::udp::endpoint(), Address()); + } + + acceptors_.erase(port); + auto remote_endpoint = socket->remote_endpoint(); + connections_[remote_endpoint] = socket; + + std::weak_ptr weak_socket = socket; + + AsyncExchange(*socket, Serialise(our_id_), [=](boost::system::error_code error, + SerialisedMessage data) { + auto socket = weak_socket.lock(); + + if (!socket) { + return handler(asio::error::operation_aborted, convert::ToAsio(remote_endpoint), + Address()); + } + + if (error) { + connections_.erase(remote_endpoint); + return handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), Address()); + } + + InputVectorStream stream(data); + Address his_id; + Parse(stream, his_id); + + id_to_endpoint_map_[his_id] = remote_endpoint; + StartReceiving(his_id, remote_endpoint, socket); + + handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), his_id); + }); + }); + }); +} + +inline void Connections::StartReceiving(const Address& id, const crux::endpoint& remote_endpoint, + const std::shared_ptr& socket) { + std::weak_ptr weak_socket = socket; + + // TODO(PeterJ): Buffer reuse + auto buffer = std::make_shared(max_message_size()); + + socket->async_receive( + boost::asio::buffer(*buffer), [=](boost::system::error_code error, size_t size) { + auto socket = weak_socket.lock(); + + if (!socket) { + return receive_queue_.Push(asio::error::operation_aborted, id, std::move(*buffer)); + } + + if (error) { + id_to_endpoint_map_.erase(id); + connections_.erase(remote_endpoint); + } + + buffer->resize(size); + receive_queue_.Push(convert::ToStd(error), id, std::move(*buffer)); + + if (error) + return; + + StartReceiving(id, remote_endpoint, socket); + }); +} + +inline boost::asio::io_service& Connections::get_io_service() { return service_; } + +inline void Connections::Shutdown() { + service_.post([=]() { + acceptors_.clear(); + connections_.clear(); + id_to_endpoint_map_.clear(); + }); +} + +} // namespace routing + +} // namespace maidsafe + +#endif // MAIDSAFE_ROUTING_CONNECTIONS_H_ diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc new file mode 100644 index 00000000..702bcbdb --- /dev/null +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -0,0 +1,87 @@ +/* Copyright 2014 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + + +#include "maidsafe/common/test.h" +#include "maidsafe/common/utils.h" + +#include "maidsafe/routing/connections.h" +#include "maidsafe/routing/tests/utils/test_utils.h" + +namespace maidsafe { + +namespace routing { + +namespace test { + +TEST(ConnectionsTest, FUNC_TwoConnections) { + boost::asio::io_service ios; + + NodeId c1_id(NodeId(RandomString(NodeId::kSize))); + NodeId c2_id(NodeId(RandomString(NodeId::kSize))); + + Connections c1(ios, c1_id); + Connections c2(ios, c2_id); + + unsigned short port = 8080; + + bool c1_finished = false; + bool c2_finished = false; + + c1.Accept(port, + [&](asio::error_code error, asio::ip::udp::endpoint, NodeId his_id) { + ASSERT_FALSE(error); + ASSERT_EQ(his_id, c2.OurId()); + std::string msg = "hello"; + + c1.Send(his_id, + std::vector(msg.begin(), msg.end()), + [&](asio::error_code error) { + ASSERT_FALSE(error); + c1.Shutdown(); + c1_finished = true; + }); + }); + + c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), + [&](asio::error_code error, NodeId his_id) { + ASSERT_FALSE(error); + ASSERT_EQ(his_id, c1.OurId()); + + c2.Receive([&, his_id](asio::error_code error, + NodeId sender_id, + const std::vector& bytes) { + ASSERT_FALSE(error); + ASSERT_EQ(sender_id, his_id); + ASSERT_EQ(std::string(bytes.begin(), bytes.end()), "hello"); + + c2.Shutdown(); + c2_finished = true; + }); + }); + + ios.run(); + + ASSERT_TRUE(c1_finished && c2_finished); +} + +} // namespace test + +} // namespace routing + +} // namespace maidsafe From b5cbd051757302567b5cd229b1d603a42b99d661 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Mon, 2 Mar 2015 19:22:25 +0100 Subject: [PATCH 06/72] First sketch of crux->routing integration --- include/maidsafe/routing/routing_node.h | 4 +- src/maidsafe/routing/connection_manager.cc | 85 +++++++++++++++++----- src/maidsafe/routing/connection_manager.h | 10 ++- src/maidsafe/routing/connections.h | 17 ++++- 4 files changed, 95 insertions(+), 21 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index f03973e4..ff2183de 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -434,7 +434,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h }); } - auto added = connection_manager_.AddNode(NodeInfo(connect.requester_id(), connect.requester_fob(), + auto added = connection_manager_.AddNodeAccept(NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints()); if (added) @@ -445,7 +445,7 @@ template void RoutingNode::HandleMessage(ConnectResponse connect_response) { if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) return; - auto added = connection_manager_.AddNode( + auto added = connection_manager_.AddNodeConnect( NodeInfo(connect_response.requester_id(), connect_response.receiver_fob(), true), connect_response.receiver_endpoints()); diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index c158fd50..ddab4b21 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -74,23 +74,74 @@ optional ConnectionManager::DropNode(const Address& their_ return GroupChanged(); } -boost::optional ConnectionManager::AddNode( - NodeInfo /*node_to_add*/, EndpointPair /*their_endpoint_pair*/) { // FIXME(Prakash) -// rudp::Contact rudp_contact(node_to_add.id, std::move(their_endpoint_pair), -// node_to_add.dht_fob.public_key()); -// asio::spawn(io_service_, [=](asio::yield_context yield) { -// asio::error_code error; -// rudp_.Add(std::move(rudp_contact), yield[error]); - -// if (!error) { -// auto added = routing_table_.AddNode(node_to_add); -// if (!added.first) { -// rudp_.Remove(node_to_add.id, asio::use_future); // become invalid for us -// } else if (added.second) { -// rudp_.Remove(added.second->id, asio::use_future); // a sacrificlal node was found -// } -// } -// }); +boost::optional ConnectionManager::AddNodeConnect( + NodeInfo node_to_add, EndpointPair their_endpoint_pair) { + + std::weak_ptr weak_connections = connections_; + + // TODO(PeterJ): Use local endpoint as well + connections_->Connect(their_endpoint_pair.external, [=](asio::error_code error, Address addr) { + if (!weak_connections.lock()) { + return; + } + + if (error || (addr != node_to_add.id)) { + return; + } + + AddNode(node_to_add); + }); + + return GroupChanged(); +} + +template void StartAccepting(std::weak_ptr weak_connections, + NodeInfo node_to_add, EndpointPair node_eps, + Handler handler) { + auto connections = weak_connections.lock(); + + if (!connections) { + return; + } + + connections->Accept(6378, [=](asio::error_code error, asio::ip::udp::endpoint, Address addr) { + if (error) { + return; + } + + if (node_to_add.id != addr) { + // Restart + StartAccepting(weak_connections, std::move(node_to_add), std::move(node_eps), + std::move(handler)); + return; + } + + handler(); + }); +} + +boost::optional ConnectionManager::AddNodeAccept( + NodeInfo node_to_add, EndpointPair their_endpoint_pair) { + + StartAccepting(connections_, node_to_add, their_endpoint_pair, [=]() { + AddNode(node_to_add); + }); + + return GroupChanged(); +} + +boost::optional ConnectionManager::AddNode(NodeInfo node_to_add) { + auto added = routing_table_.AddNode(node_to_add); + + if (!added.first) { + connections_->Drop(node_to_add.id); + } else if (added.second) { + connections_->Drop(node_to_add.id); + } + + // FIXME: It is incorrect to assume the GroupChanged will reflect changes made + // by the previous Drop command because that command will execute its business + // in a separate thread (Same in the AddNodeAccept function and others). return GroupChanged(); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 6d7c763a..ba618e0e 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -52,6 +52,7 @@ destiations. In that case request a close_group message for this node. #include "maidsafe/routing/routing_table.h" #include "maidsafe/routing/types.h" #include "maidsafe/routing/peer_node.h" +#include "maidsafe/routing/connections.h" namespace maidsafe { @@ -75,8 +76,11 @@ class ConnectionManager { // routing wishes to drop a specific node (may be a node we cannot connect to) boost::optional DropNode(const Address& their_id); - boost::optional AddNode(NodeInfo node_to_add, + boost::optional AddNodeConnect(NodeInfo node_to_add, EndpointPair their_endpoint_pair); + boost::optional AddNodeAccept(NodeInfo node_to_add, + EndpointPair their_endpoint_pair); + std::vector OurCloseGroup() const { return routing_table_.OurCloseGroup(); } size_t CloseGroupBucketDistance() const { @@ -101,6 +105,9 @@ class ConnectionManager { uint32_t Size() { return routing_table_.Size(); } + private: + boost::optional AddNode(NodeInfo node_to_add); + private: boost::optional GroupChanged(); @@ -109,6 +116,7 @@ class ConnectionManager { RoutingTable routing_table_; std::vector
current_close_group_; std::function group_changed_functor_; + std::shared_ptr connections_; }; } // namespace routing diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 60c146c7..546e7ecb 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -62,7 +62,7 @@ class Connections { template void Connect(asio::ip::udp::endpoint, Handler); - template + template void Accept(unsigned short port, const Handler); void Drop(const Address& their_id); @@ -288,6 +288,21 @@ inline void Connections::Shutdown() { }); } +inline void Connections::Drop(const Address& their_id) { + service_.post([=]() { + // TODO: Migth it be that it is in connections_ but not in the id_to_endpoint_map_? + // I.e. that above layers would wan't to remove by ID nodes which were not + // yet connected? + auto i = id_to_endpoint_map_.find(their_id); + + if (i == id_to_endpoint_map_.end()) { + return; + } + + connections_.erase(i->second); + }); +} + } // namespace routing } // namespace maidsafe From 59cd68f67c123956a880c66fa683f7f8bc96d764 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 3 Mar 2015 12:05:36 +0100 Subject: [PATCH 07/72] Renames few functions --- include/maidsafe/routing/routing_node.h | 2 +- src/maidsafe/routing/async_queue.h | 1 + src/maidsafe/routing/connection_manager.cc | 8 ++++---- src/maidsafe/routing/connection_manager.h | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index ff2183de..6c433f67 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -445,7 +445,7 @@ template void RoutingNode::HandleMessage(ConnectResponse connect_response) { if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) return; - auto added = connection_manager_.AddNodeConnect( + auto added = connection_manager_.AddNode( NodeInfo(connect_response.requester_id(), connect_response.receiver_fob(), true), connect_response.receiver_endpoints()); diff --git a/src/maidsafe/routing/async_queue.h b/src/maidsafe/routing/async_queue.h index dc50bbe6..0bf07947 100644 --- a/src/maidsafe/routing/async_queue.h +++ b/src/maidsafe/routing/async_queue.h @@ -35,6 +35,7 @@ namespace detail { namespace helper { +// For more info in ApplyTuple see: https://www.preney.ca/paul/archives/486 template struct Index {}; diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index ddab4b21..2e8ff399 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -74,7 +74,7 @@ optional ConnectionManager::DropNode(const Address& their_ return GroupChanged(); } -boost::optional ConnectionManager::AddNodeConnect( +boost::optional ConnectionManager::AddNode( NodeInfo node_to_add, EndpointPair their_endpoint_pair) { std::weak_ptr weak_connections = connections_; @@ -89,7 +89,7 @@ boost::optional ConnectionManager::AddNodeConnect( return; } - AddNode(node_to_add); + AddToRoutingTable(node_to_add); }); return GroupChanged(); @@ -124,13 +124,13 @@ boost::optional ConnectionManager::AddNodeAccept( NodeInfo node_to_add, EndpointPair their_endpoint_pair) { StartAccepting(connections_, node_to_add, their_endpoint_pair, [=]() { - AddNode(node_to_add); + AddToRoutingTable(node_to_add); }); return GroupChanged(); } -boost::optional ConnectionManager::AddNode(NodeInfo node_to_add) { +boost::optional ConnectionManager::AddToRoutingTable(NodeInfo node_to_add) { auto added = routing_table_.AddNode(node_to_add); if (!added.first) { diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index ba618e0e..eb41efd6 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -76,7 +76,7 @@ class ConnectionManager { // routing wishes to drop a specific node (may be a node we cannot connect to) boost::optional DropNode(const Address& their_id); - boost::optional AddNodeConnect(NodeInfo node_to_add, + boost::optional AddNode(NodeInfo node_to_add, EndpointPair their_endpoint_pair); boost::optional AddNodeAccept(NodeInfo node_to_add, EndpointPair their_endpoint_pair); @@ -106,7 +106,7 @@ class ConnectionManager { uint32_t Size() { return routing_table_.Size(); } private: - boost::optional AddNode(NodeInfo node_to_add); + boost::optional AddToRoutingTable(NodeInfo node_to_add); private: boost::optional GroupChanged(); From 26df0b755964555ddd509710ab2ce79fdcc40abc Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 3 Mar 2015 12:34:36 +0100 Subject: [PATCH 08/72] Sketch of how receiving works with crux --- include/maidsafe/routing/routing_node.h | 11 +++++++--- src/maidsafe/routing/connection_manager.cc | 24 ++++++++++++++++++++-- src/maidsafe/routing/connection_manager.h | 8 +++++++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 6c433f67..9523395e 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -112,7 +112,7 @@ class RoutingNode { void HandleMessage(routing::Post post, MessageHeader original_header); bool TryCache(MessageTypeTag tag, MessageHeader header, Address name); Authority OurAuthority(const Address& element, const MessageHeader& header) const; - void MessageReceived(Address peer_id, SerialisedMessage serialised_message); + void MessageReceived(asio::error_code, Address peer_id, SerialisedMessage serialised_message); void ConnectionLost(Address peer); void OnCloseGroupChanged(CloseGroupDifference close_group_difference); SourceAddress OurSourceAddress() const; @@ -158,7 +158,11 @@ RoutingNode::RoutingNode() message_id_(RandomUint32()), bootstrap_node_(boost::none), bootstrap_handler_(), - connection_manager_(crux_asio_service_.service(), Address(our_fob_.name()->string())), + connection_manager_(crux_asio_service_.service(), Address(our_fob_.name()->string()), + ConnectionManager::OnReceive()), + //[=](asio::error_code error, Address address, SerialisedMessage msg) { + //MessageReceived(error, std::move(address), std::move(msg)); + //}), filter_(std::chrono::minutes(20)), sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), @@ -286,7 +290,8 @@ void RoutingNode::ConnectToCloseGroup() { } template -void RoutingNode::MessageReceived(NodeId /* peer_id */, +void RoutingNode::MessageReceived(asio::error_code /*error*/, + NodeId /* peer_id */, SerialisedMessage serialised_message) { InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 2e8ff399..c3dbcd20 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -44,11 +44,17 @@ using std::move; using boost::none_t; using boost::optional; -ConnectionManager::ConnectionManager(boost::asio::io_service& ios, Address our_id) +ConnectionManager::ConnectionManager(boost::asio::io_service& ios, Address our_id, + OnReceive on_receive) : mutex_(), io_service_(ios), + boost_io_service_(1), routing_table_(our_id), - current_close_group_() {} + on_receive_(std::move(on_receive)), + current_close_group_(), + connections_(new Connections(boost_io_service_.service(), our_id)) { + StartReceiving(); +} bool ConnectionManager::SuggestNodeToAdd(const Address& node_to_add) const { return routing_table_.CheckNode(node_to_add); @@ -165,6 +171,20 @@ boost::optional ConnectionManager::GroupChanged() { return boost::none; } +void ConnectionManager::StartReceiving() { + std::weak_ptr weak_connections = connections_; + + connections_->Receive([=](asio::error_code error, Address address, + const SerialisedMessage& message) { + if (!weak_connections.lock()) return; + auto h = std::move(on_receive_); + h(error, std::move(address), std::move(message)); + if (!weak_connections.lock()) return; + on_receive_ = std::move(h); + StartReceiving(); + }); +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index eb41efd6..6fb66b7e 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -62,7 +62,10 @@ class ConnectionManager { using PublicPmid = passport::PublicPmid; public: - ConnectionManager(boost::asio::io_service& ios, Address our_id); + using OnReceive = std::function; + + public: + ConnectionManager(boost::asio::io_service& ios, Address our_id, OnReceive on_receive); ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; @@ -107,13 +110,16 @@ class ConnectionManager { private: boost::optional AddToRoutingTable(NodeInfo node_to_add); + void StartReceiving(); private: boost::optional GroupChanged(); std::mutex mutex_; boost::asio::io_service& io_service_; + BoostAsioService boost_io_service_; RoutingTable routing_table_; + OnReceive on_receive_; std::vector
current_close_group_; std::function group_changed_functor_; std::shared_ptr connections_; From e80c7759a31ef98e29c52c9eca6009fd0b57d939 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 3 Mar 2015 16:11:44 +0100 Subject: [PATCH 09/72] Removes the io_service& argument from ConnectionManagers constructor --- include/maidsafe/routing/routing_node.h | 7 ++----- src/maidsafe/routing/connection_manager.cc | 4 +--- src/maidsafe/routing/connection_manager.h | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 9523395e..fd980093 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -132,7 +132,6 @@ class RoutingNode { private: using unique_identifier = std::pair; - BoostAsioService crux_asio_service_; AsioService asio_service_; passport::Pmid our_fob_; std::atomic message_id_; @@ -152,13 +151,12 @@ void Connections_Send(const Address&, const SerialisedMessage&, Handler) {} template RoutingNode::RoutingNode() - : crux_asio_service_(1), - asio_service_(4), + : asio_service_(4), our_fob_(passport::CreatePmidAndSigner().first), message_id_(RandomUint32()), bootstrap_node_(boost::none), bootstrap_handler_(), - connection_manager_(crux_asio_service_.service(), Address(our_fob_.name()->string()), + connection_manager_(Address(our_fob_.name()->string()), ConnectionManager::OnReceive()), //[=](asio::error_code error, Address address, SerialisedMessage msg) { //MessageReceived(error, std::move(address), std::move(msg)); @@ -199,7 +197,6 @@ RoutingNode::RoutingNode() template RoutingNode::~RoutingNode() { - crux_asio_service_.Stop(); } template diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index c3dbcd20..096bc4cf 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -44,10 +44,8 @@ using std::move; using boost::none_t; using boost::optional; -ConnectionManager::ConnectionManager(boost::asio::io_service& ios, Address our_id, - OnReceive on_receive) +ConnectionManager::ConnectionManager(Address our_id, OnReceive on_receive) : mutex_(), - io_service_(ios), boost_io_service_(1), routing_table_(our_id), on_receive_(std::move(on_receive)), diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 6fb66b7e..a5dcfc24 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -65,7 +65,7 @@ class ConnectionManager { using OnReceive = std::function; public: - ConnectionManager(boost::asio::io_service& ios, Address our_id, OnReceive on_receive); + ConnectionManager(Address our_id, OnReceive on_receive); ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; @@ -116,7 +116,6 @@ class ConnectionManager { boost::optional GroupChanged(); std::mutex mutex_; - boost::asio::io_service& io_service_; BoostAsioService boost_io_service_; RoutingTable routing_table_; OnReceive on_receive_; From 8b40e95f11acc07c5d2bdfc71fcfa17e372b676f Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 3 Mar 2015 16:41:40 +0100 Subject: [PATCH 10/72] ConnectionManager::{AddNode,AddNodeAccept} pass group difference ot its handler --- include/maidsafe/routing/routing_node.h | 62 +++++++++++++--------- src/maidsafe/routing/connection_manager.cc | 16 +++--- src/maidsafe/routing/connection_manager.h | 7 ++- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index fd980093..2dbdf045 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -142,6 +142,8 @@ class RoutingNode { Sentinel sentinel_; LruCache cache_; std::vector
connected_nodes_; + + std::shared_ptr destroy_indicator_; }; // FIXME(Prakash) temporary code. To be replaced by connections::Send() @@ -164,7 +166,8 @@ RoutingNode::RoutingNode() filter_(std::chrono::minutes(20)), sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), - connected_nodes_() { + connected_nodes_(), + destroy_indicator_(new boost::none_t) { // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); @@ -436,37 +439,48 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h }); } - auto added = connection_manager_.AddNodeAccept(NodeInfo(connect.requester_id(), connect.requester_fob(), - true), connect.requester_endpoints()); + std::weak_ptr destroy_guard = destroy_indicator_; - if (added) - static_cast(this)->HandleChurn(*added); + connection_manager_.AddNodeAccept + (NodeInfo(connect.requester_id(), connect.requester_fob(), true), + connect.requester_endpoints(), + [=](boost::optional added) { + if (!destroy_guard.lock()) return; + if (added) + static_cast(this)->HandleChurn(*added); + }); } template void RoutingNode::HandleMessage(ConnectResponse connect_response) { if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) return; - auto added = connection_manager_.AddNode( + + std::weak_ptr destroy_guard = destroy_indicator_; + + connection_manager_.AddNode( NodeInfo(connect_response.requester_id(), connect_response.receiver_fob(), true), - connect_response.receiver_endpoints()); - - auto target = connect_response.requester_id(); - // TODO(Prakash): below may not be reqd if connecting socket also takes place in connection mgr - // rudp_.Add( - // rudp::Contact(connect_response.receiver_id(), connect_response.receiver_endpoints(), - // connect_response.receiver_fob().public_key()), - // [target, added, this](asio::error_code error) { - // if (error) { - // this->connection_manager_.DropNode(target); - // return; - // } - if (added) - static_cast(this)->HandleChurn(*added); - if (connection_manager_.Size() >= QuorumSize) { -// rudp_.Remove(*bootstrap_node_, asio::use_future).get(); // FIXME (Prakash) - bootstrap_node_ = boost::none; - } + connect_response.receiver_endpoints(), [=](boost::optional added) { + if (!destroy_guard.lock()) return; + + auto target = connect_response.requester_id(); + // TODO(Prakash): below may not be reqd if connecting socket also takes place in connection mgr + // rudp_.Add( + // rudp::Contact(connect_response.receiver_id(), connect_response.receiver_endpoints(), + // connect_response.receiver_fob().public_key()), + // [target, added, this](asio::error_code error) { + // if (error) { + // this->connection_manager_.DropNode(target); + // return; + // } + if (added) + static_cast(this)->HandleChurn(*added); + if (connection_manager_.Size() >= QuorumSize) { + // rudp_.Remove(*bootstrap_node_, asio::use_future).get(); // FIXME (Prakash) + bootstrap_node_ = boost::none; + } + }); + } template diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 096bc4cf..d2467340 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -78,8 +78,8 @@ optional ConnectionManager::DropNode(const Address& their_ return GroupChanged(); } -boost::optional ConnectionManager::AddNode( - NodeInfo node_to_add, EndpointPair their_endpoint_pair) { +void ConnectionManager::AddNode( + NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode on_node_added) { std::weak_ptr weak_connections = connections_; @@ -93,10 +93,8 @@ boost::optional ConnectionManager::AddNode( return; } - AddToRoutingTable(node_to_add); + on_node_added(AddToRoutingTable(node_to_add)); }); - - return GroupChanged(); } template void StartAccepting(std::weak_ptr weak_connections, @@ -124,14 +122,12 @@ template void StartAccepting(std::weak_ptr weak_conn }); } -boost::optional ConnectionManager::AddNodeAccept( - NodeInfo node_to_add, EndpointPair their_endpoint_pair) { +void ConnectionManager::AddNodeAccept(NodeInfo node_to_add, EndpointPair their_endpoint_pair, + OnAddNode on_node_added) { StartAccepting(connections_, node_to_add, their_endpoint_pair, [=]() { - AddToRoutingTable(node_to_add); + on_node_added(AddToRoutingTable(node_to_add)); }); - - return GroupChanged(); } boost::optional ConnectionManager::AddToRoutingTable(NodeInfo node_to_add) { diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index a5dcfc24..a78a322f 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -63,6 +63,7 @@ class ConnectionManager { public: using OnReceive = std::function; + using OnAddNode = std::function)>; public: ConnectionManager(Address our_id, OnReceive on_receive); @@ -79,10 +80,8 @@ class ConnectionManager { // routing wishes to drop a specific node (may be a node we cannot connect to) boost::optional DropNode(const Address& their_id); - boost::optional AddNode(NodeInfo node_to_add, - EndpointPair their_endpoint_pair); - boost::optional AddNodeAccept(NodeInfo node_to_add, - EndpointPair their_endpoint_pair); + void AddNode(NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode); + void AddNodeAccept(NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode); std::vector OurCloseGroup() const { return routing_table_.OurCloseGroup(); } From 167d896daa01b7ef70321104f528cc4ec47c187c Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 3 Mar 2015 23:46:16 +0100 Subject: [PATCH 11/72] RoutingNode now starts listening right after construction Also some compilation fixes --- include/maidsafe/routing/routing_node.h | 27 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 2dbdf045..7644db48 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -159,10 +159,9 @@ RoutingNode::RoutingNode() bootstrap_node_(boost::none), bootstrap_handler_(), connection_manager_(Address(our_fob_.name()->string()), - ConnectionManager::OnReceive()), - //[=](asio::error_code error, Address address, SerialisedMessage msg) { - //MessageReceived(error, std::move(address), std::move(msg)); - //}), + [=](asio::error_code error, Address address, SerialisedMessage msg) { + MessageReceived(error, std::move(address), std::move(msg)); + }), filter_(std::chrono::minutes(20)), sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), @@ -458,12 +457,15 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { std::weak_ptr destroy_guard = destroy_indicator_; + // Workaround because ConnectResponse isn't copyconstructibe. + auto response_ptr = std::make_shared(std::move(connect_response)); + connection_manager_.AddNode( - NodeInfo(connect_response.requester_id(), connect_response.receiver_fob(), true), - connect_response.receiver_endpoints(), [=](boost::optional added) { + NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), + response_ptr->receiver_endpoints(), [=](boost::optional added) { if (!destroy_guard.lock()) return; - auto target = connect_response.requester_id(); + auto target = response_ptr->requester_id(); // TODO(Prakash): below may not be reqd if connecting socket also takes place in connection mgr // rudp_.Add( // rudp::Contact(connect_response.receiver_id(), connect_response.receiver_endpoints(), @@ -485,9 +487,14 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { template void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader original_header) { - auto group = connection_manager_.OurCloseGroup(); + auto close_group = connection_manager_.OurCloseGroup(); // add ourselves - group.emplace_back(NodeInfo(OurId(), passport::PublicPmid(our_fob_))); + std::vector group; + group.reserve(close_group.size() + 1); + for (auto& node_info : close_group) { + group.push_back(std::move(node_info.dht_fob)); + } + group.emplace_back(passport::PublicPmid(our_fob_)); FindGroupResponse response(find_group.target_id(), std::move(group)); MessageHeader header(DestinationAddress(original_header.ReturnDestinationAddress()), SourceAddress(OurSourceAddress(GroupAddress(find_group.target_id()))), @@ -514,7 +521,7 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, SourceAddress{OurSourceAddress()}, ++message_id_, Authority::nae_manager); for (const auto& target : connection_manager_.GetTarget(node_id)) Connections_Send( - Serialise(header, MessageToTag::value(), message), [](asio::error_code) {}); + target.id, Serialise(header, MessageToTag::value(), message), [](asio::error_code) {}); } } From 4e9a9b1b14013c71bdbaba88ef2f0180ecef05fb Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 01:12:23 +0100 Subject: [PATCH 12/72] Connections class exchanges endpoints on connection establishment Exchanges how each connection sees the other one --- src/maidsafe/routing/connection_manager.cc | 7 +-- src/maidsafe/routing/connections.h | 46 +++++++++++-------- .../routing/tests/routing_connections_test.cc | 5 +- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index d2467340..65228777 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -32,7 +32,6 @@ #include "maidsafe/routing/peer_node.h" #include "maidsafe/routing/routing_table.h" #include "maidsafe/routing/types.h" -#include "maidsafe/routing/async_exchange.h" namespace maidsafe { @@ -84,7 +83,8 @@ void ConnectionManager::AddNode( std::weak_ptr weak_connections = connections_; // TODO(PeterJ): Use local endpoint as well - connections_->Connect(their_endpoint_pair.external, [=](asio::error_code error, Address addr) { + connections_->Connect(their_endpoint_pair.external, + [=](asio::error_code error, Address addr, Endpoint) { if (!weak_connections.lock()) { return; } @@ -106,7 +106,8 @@ template void StartAccepting(std::weak_ptr weak_conn return; } - connections->Accept(6378, [=](asio::error_code error, asio::ip::udp::endpoint, Address addr) { + connections->Accept(6378, + [=](asio::error_code error, asio::ip::udp::endpoint, Address addr, Endpoint /*our_endpoint*/) { if (error) { return; } diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 546e7ecb..95a3e5a5 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -35,6 +35,7 @@ #include "maidsafe/routing/async_queue.h" #include "maidsafe/routing/async_exchange.h" #include "maidsafe/routing/types.h" +#include "maidsafe/routing/utils.h" namespace maidsafe { @@ -59,10 +60,10 @@ class Connections { template void Receive(Handler); - template + template void Connect(asio::ip::udp::endpoint, Handler); - template + template void Accept(unsigned short port, const Handler); void Drop(const Address& their_id); @@ -136,8 +137,10 @@ void Connections::Receive(Handler handler) { inline Connections::~Connections() { Shutdown(); } -template +template void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { + using asio_endpoint = asio::ip::udp::endpoint; + service_.post([=]() { crux::endpoint unspecified_ep(boost::asio::ip::udp::v4(), 0); auto socket = std::make_shared(service_, unspecified_ep); @@ -145,7 +148,7 @@ void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { auto insert_result = connections_.insert(std::make_pair(convert::ToBoost(endpoint), socket)); if (!insert_result.second) { - return handler(asio::error::already_started, Address()); + return handler(asio::error::already_started, Address(), asio_endpoint()); } std::weak_ptr weak_socket = socket; @@ -154,37 +157,39 @@ void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { auto socket = weak_socket.lock(); if (!socket) { - return handler(asio::error::operation_aborted, Address()); + return handler(asio::error::operation_aborted, Address(), asio_endpoint()); } if (error) { - return handler(convert::ToStd(error), Address()); + return handler(convert::ToStd(error), Address(), asio_endpoint()); } auto remote_endpoint = socket->remote_endpoint(); connections_[remote_endpoint] = socket; + auto his_endpoint = convert::ToAsio(socket->remote_endpoint()); - AsyncExchange(*socket, Serialise(our_id_), + AsyncExchange(*socket, Serialise(our_id_, his_endpoint), [=](boost::system::error_code error, SerialisedMessage data) { auto socket = weak_socket.lock(); if (!socket) { - return handler(asio::error::operation_aborted, Address()); + return handler(asio::error::operation_aborted, Address(), asio_endpoint()); } if (error) { connections_.erase(remote_endpoint); - return handler(convert::ToStd(error), Address()); + return handler(convert::ToStd(error), Address(), asio_endpoint()); } InputVectorStream stream(data); Address his_id; - Parse(stream, his_id); + asio::ip::udp::endpoint our_endpoint; + Parse(stream, his_id, our_endpoint); id_to_endpoint_map_[his_id] = remote_endpoint; StartReceiving(his_id, remote_endpoint, socket); - handler(convert::ToStd(error), his_id); + handler(convert::ToStd(error), his_id, our_endpoint); }); }); }); @@ -208,41 +213,44 @@ void Connections::Accept(unsigned short port, const Handler handler) { acceptor->async_accept(*socket, [=](boost::system::error_code error) { if (!weak_acceptor.lock()) { - return handler(asio::error::operation_aborted, asio::ip::udp::endpoint(), Address()); + return handler(asio::error::operation_aborted, Endpoint(), Address(), Endpoint()); } if (error) { - return handler(asio::error::operation_aborted, asio::ip::udp::endpoint(), Address()); + return handler(asio::error::operation_aborted, Endpoint(), Address(), Endpoint()); } acceptors_.erase(port); auto remote_endpoint = socket->remote_endpoint(); connections_[remote_endpoint] = socket; + auto his_endpoint = convert::ToAsio(socket->remote_endpoint()); std::weak_ptr weak_socket = socket; - AsyncExchange(*socket, Serialise(our_id_), [=](boost::system::error_code error, - SerialisedMessage data) { + AsyncExchange(*socket, Serialise(our_id_, his_endpoint), [=](boost::system::error_code error, + SerialisedMessage data) { auto socket = weak_socket.lock(); if (!socket) { return handler(asio::error::operation_aborted, convert::ToAsio(remote_endpoint), - Address()); + Address(), Endpoint()); } if (error) { connections_.erase(remote_endpoint); - return handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), Address()); + return handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), Address(), + Endpoint()); } InputVectorStream stream(data); Address his_id; - Parse(stream, his_id); + Endpoint our_endpoint; + Parse(stream, his_id, our_endpoint); id_to_endpoint_map_[his_id] = remote_endpoint; StartReceiving(his_id, remote_endpoint, socket); - handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), his_id); + handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), his_id, our_endpoint); }); }); }); diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc index 702bcbdb..af912796 100644 --- a/src/maidsafe/routing/tests/routing_connections_test.cc +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -44,9 +44,10 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { bool c2_finished = false; c1.Accept(port, - [&](asio::error_code error, asio::ip::udp::endpoint, NodeId his_id) { + [&](asio::error_code error, asio::ip::udp::endpoint, NodeId his_id, Endpoint my_ep) { ASSERT_FALSE(error); ASSERT_EQ(his_id, c2.OurId()); + ASSERT_EQ(my_ep.port(), port); std::string msg = "hello"; c1.Send(his_id, @@ -59,7 +60,7 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { }); c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), - [&](asio::error_code error, NodeId his_id) { + [&](asio::error_code error, NodeId his_id, Endpoint /*my_ep*/) { ASSERT_FALSE(error); ASSERT_EQ(his_id, c1.OurId()); From 01c057d0e9d9f236f7f417c11c029ed68ef324a9 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 01:38:23 +0100 Subject: [PATCH 13/72] Info about our endpoint is propagated up to the RoutingNode It is the endpoint we receive from the other end after being connected. It represents us as seen from the other end. --- include/maidsafe/routing/routing_node.h | 5 +++-- src/maidsafe/routing/connection_manager.cc | 13 +++++++------ src/maidsafe/routing/connection_manager.h | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 7644db48..951a175d 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -443,7 +443,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h connection_manager_.AddNodeAccept (NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints(), - [=](boost::optional added) { + [=](boost::optional added, Endpoint /* our_endpoint */) { if (!destroy_guard.lock()) return; if (added) static_cast(this)->HandleChurn(*added); @@ -462,7 +462,8 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { connection_manager_.AddNode( NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), - response_ptr->receiver_endpoints(), [=](boost::optional added) { + response_ptr->receiver_endpoints(), + [=](boost::optional added, Endpoint /* our_endpoint */) { if (!destroy_guard.lock()) return; auto target = response_ptr->requester_id(); diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 65228777..a2414c4c 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -84,7 +84,7 @@ void ConnectionManager::AddNode( // TODO(PeterJ): Use local endpoint as well connections_->Connect(their_endpoint_pair.external, - [=](asio::error_code error, Address addr, Endpoint) { + [=](asio::error_code error, Address addr, Endpoint our_endpoint) { if (!weak_connections.lock()) { return; } @@ -93,7 +93,7 @@ void ConnectionManager::AddNode( return; } - on_node_added(AddToRoutingTable(node_to_add)); + on_node_added(AddToRoutingTable(node_to_add), our_endpoint); }); } @@ -106,8 +106,9 @@ template void StartAccepting(std::weak_ptr weak_conn return; } + // TODO(Team): What endpoint should we accept on? connections->Accept(6378, - [=](asio::error_code error, asio::ip::udp::endpoint, Address addr, Endpoint /*our_endpoint*/) { + [=](asio::error_code error, asio::ip::udp::endpoint, Address addr, Endpoint our_endpoint) { if (error) { return; } @@ -119,15 +120,15 @@ template void StartAccepting(std::weak_ptr weak_conn return; } - handler(); + handler(our_endpoint); }); } void ConnectionManager::AddNodeAccept(NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode on_node_added) { - StartAccepting(connections_, node_to_add, their_endpoint_pair, [=]() { - on_node_added(AddToRoutingTable(node_to_add)); + StartAccepting(connections_, node_to_add, their_endpoint_pair, [=](Endpoint our_endpoint) { + on_node_added(AddToRoutingTable(node_to_add), our_endpoint); }); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index a78a322f..799f5680 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -63,7 +63,7 @@ class ConnectionManager { public: using OnReceive = std::function; - using OnAddNode = std::function)>; + using OnAddNode = std::function, Endpoint)>; public: ConnectionManager(Address our_id, OnReceive on_receive); From 0a2ff88019386df7389a7381c0f4bb7aacb0b23a Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 16:15:03 +0100 Subject: [PATCH 14/72] Replaces the dummy send function with a proper one In RoutingNode --- include/maidsafe/routing/routing_node.h | 39 ++++++++++------------- src/maidsafe/routing/connection_manager.h | 9 ++++++ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 951a175d..c2414be6 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -146,11 +146,6 @@ class RoutingNode { std::shared_ptr destroy_indicator_; }; -// FIXME(Prakash) temporary code. To be replaced by connections::Send() -// Alternatively, All Send go via Connection manager to stop misuse of Send functionality here -template -void Connections_Send(const Address&, const SerialisedMessage&, Handler) {} - template RoutingNode::RoutingNode() : asio_service_(4), @@ -212,7 +207,7 @@ GetReturn RoutingNode::Get(Identity name, CompletionToke GetData request(DataType::Tag::kValue, name, OurSourceAddress()); auto message(Serialise(our_header, MessageToTag::value(), request)); for (const auto& target : connection_manager_.GetTarget(Address(name.string()))) { - Connections_Send(target.id, message, [](asio::error_code) {}); // FIXME(Prakash) + connection_manager_.Send(target.id, message, [](asio::error_code) {}); } }); return result.get(); @@ -236,7 +231,7 @@ PutReturn RoutingNode::Put(Address to, DataType data, // fixme data should serialise properly and not require the above call to serialse() auto message(Serialise(our_header, MessageToTag::value(), request)); for (const auto& target : connection_manager_.GetTarget(to)) { - Connections_Send(target.id, message, [](asio::error_code) {}); + connection_manager_.Send(target.id, message, [](asio::error_code) {}); } }); return result.get(); @@ -256,7 +251,7 @@ PostReturn RoutingNode::Post(Address to, FunctorType fun auto message(Serialise(our_header, MessageToTag::value(), request)); for (const auto& target : connection_manager_.GetTarget(to)) { - Connections_Send(target.id, message, [](asio::error_code) {}); + connection_manager_.Send(target.id, message, [](asio::error_code) {}); } }); return result.get(); @@ -270,8 +265,8 @@ void RoutingNode::ConnectToCloseGroup() { if (bootstrap_node_) { // this is special case , so probably have special function in connection manager to send to // bootstrap node - Connections_Send(*bootstrap_node_, Serialise(header, MessageToTag::value(), message), - [](asio::error_code error) { + auto message = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(*bootstrap_node_, std::move(message), [](asio::error_code error) { if (error) { LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); } @@ -279,8 +274,8 @@ void RoutingNode::ConnectToCloseGroup() { return; } for (const auto& target : connection_manager_.GetTarget(OurId())) { - Connections_Send(target.id, Serialise(header, MessageToTag::value(), message), - [](asio::error_code error) { + auto message = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(target.id, std::move(message), [](asio::error_code error) { if (error) { LOG(kWarning) << "rudp cannot send" << error.message(); } @@ -336,7 +331,7 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, // send to next node(s) even our close group (swarm mode) for (const auto& target : connection_manager_.GetTarget(header.Destination().first)) { - Connections_Send(target.id, serialised_message, [](asio::error_code error) { + connection_manager_.Send(target.id, serialised_message, [](asio::error_code error) { if (error) { LOG(kWarning) << "cannot send" << error.message(); } @@ -431,11 +426,9 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h // shutdown // :24/01/2015 for (auto& target : targets) { - Connections_Send(target.id, Serialise(header, MessageToTag::value(), respond), - [connect, this](asio::error_code error_code) { - if (error_code) - return; - }); + // FIXME(Team): Do we need to serialize this for each target? + auto message = Serialise(header, MessageToTag::value(), respond); + connection_manager_.Send(target.id, std::move(message), [](asio::error_code) {}); } std::weak_ptr destroy_guard = destroy_indicator_; @@ -503,7 +496,7 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi asymm::Sign(Serialise(response), our_fob_.private_key())); auto message(Serialise(header, MessageToTag::value(), response)); for (const auto& node : connection_manager_.GetTarget(original_header.FromNode())) { - Connections_Send(node.id, message, [](asio::error_code) {}); + connection_manager_.Send(node.id, message, [](asio::error_code) {}); } } @@ -520,9 +513,11 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, Connect message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); MessageHeader header(DestinationAddress(std::make_pair(Destination(node_id), boost::none)), SourceAddress{OurSourceAddress()}, ++message_id_, Authority::nae_manager); - for (const auto& target : connection_manager_.GetTarget(node_id)) - Connections_Send( - target.id, Serialise(header, MessageToTag::value(), message), [](asio::error_code) {}); + for (const auto& target : connection_manager_.GetTarget(node_id)) { + // FIXME(Team): Do the serialisation only once as it doesn't depend on the target. + auto message_data = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(target.id, std::move(message_data), [](asio::error_code) {}); + } } } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 799f5680..e2a47938 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -107,6 +107,9 @@ class ConnectionManager { uint32_t Size() { return routing_table_.Size(); } + template + void Send(const Address&, const SerialisedMessage&, Handler); + private: boost::optional AddToRoutingTable(NodeInfo node_to_add); void StartReceiving(); @@ -123,6 +126,12 @@ class ConnectionManager { std::shared_ptr connections_; }; +template +void ConnectionManager::Send(const Address& addr, const SerialisedMessage& message, + Handler handler) { + connections_->Send(addr, message, std::move(handler)); +} + } // namespace routing } // namespace maidsafe From eac48ce0cb576f985bf68c3968d1a6e9358eddf4 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 17:48:42 +0100 Subject: [PATCH 15/72] RoutingNode starts bootstrap in its constructor to find out its external endpoint. --- include/maidsafe/routing/routing_node.h | 19 +++++++++++++++++++ src/maidsafe/routing/connection_manager.cc | 11 +++++++---- src/maidsafe/routing/connection_manager.h | 12 +++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index c2414be6..174cb4ee 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -136,6 +136,7 @@ class RoutingNode { passport::Pmid our_fob_; std::atomic message_id_; boost::optional
bootstrap_node_; + boost::optional bootstrap_endpoint_; BootstrapHandler bootstrap_handler_; ConnectionManager connection_manager_; LruCache filter_; @@ -179,6 +180,24 @@ RoutingNode::RoutingNode() // } // }); + auto bootstrap_contacts = bootstrap_handler_.ReadBootstrapContacts(); + + for (const auto& contact : bootstrap_contacts) { + connection_manager_.Connect(contact.endpoint_pair.external, + [=](asio::error_code error, Address addr, Endpoint our_endpoint) { + if (error) { + return; + } + if (addr != contact.id) { + return; + } + // FIXME(Team): Thread safety. + bootstrap_node_ = contact.id; + bootstrap_endpoint_ = our_endpoint; + ConnectToCloseGroup(); + }); + } + // for (auto& node : bootstrap_handler_.ReadBootstrapContacts()) { // rudp_.Add(node, [node, this](asio::error_code error) { // if (!error) { diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index a2414c4c..d3bbd2d0 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -71,10 +71,13 @@ boost::optional ConnectionManager::LostNetworkConnection( return GroupChanged(); } -optional ConnectionManager::DropNode(const Address& their_id) { - routing_table_.DropNode(their_id); - // FIXME(Prakash) remove connection ? - return GroupChanged(); +//optional ConnectionManager::DropNode(const Address& their_id) { +// routing_table_.DropNode(their_id); +// // FIXME(Prakash) remove connection ? +// return GroupChanged(); +//} +void ConnectionManager::DropNode(const Address& their_id) { + connections_->Drop(their_id); } void ConnectionManager::AddNode( diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index e2a47938..22918ae7 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -79,7 +79,9 @@ class ConnectionManager { boost::optional LostNetworkConnection(const Address& node); // routing wishes to drop a specific node (may be a node we cannot connect to) - boost::optional DropNode(const Address& their_id); + //boost::optional DropNode(const Address& their_id); + void DropNode(const Address& their_id); + void AddNode(NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode); void AddNodeAccept(NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode); @@ -110,6 +112,9 @@ class ConnectionManager { template void Send(const Address&, const SerialisedMessage&, Handler); + template + void Connect(asio::ip::udp::endpoint, Handler); + private: boost::optional AddToRoutingTable(NodeInfo node_to_add); void StartReceiving(); @@ -132,6 +137,11 @@ void ConnectionManager::Send(const Address& addr, const SerialisedMessage& messa connections_->Send(addr, message, std::move(handler)); } +template +void ConnectionManager::Connect(asio::ip::udp::endpoint remote_endpoint, Handler handler) { + connections_->Connect(remote_endpoint, std::move(handler)); +} + } // namespace routing } // namespace maidsafe From 66b49184a4a7bfe107400d2a93b2711ecc0feb91 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 17:57:52 +0100 Subject: [PATCH 16/72] Fixes compilation --- include/maidsafe/routing/routing_node.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 174cb4ee..97a7f77d 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -284,8 +284,8 @@ void RoutingNode::ConnectToCloseGroup() { if (bootstrap_node_) { // this is special case , so probably have special function in connection manager to send to // bootstrap node - auto message = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(*bootstrap_node_, std::move(message), [](asio::error_code error) { + auto msg_data = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(*bootstrap_node_, std::move(msg_data), [](asio::error_code error) { if (error) { LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); } @@ -293,8 +293,8 @@ void RoutingNode::ConnectToCloseGroup() { return; } for (const auto& target : connection_manager_.GetTarget(OurId())) { - auto message = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(target.id, std::move(message), [](asio::error_code error) { + auto msg_data = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(target.id, std::move(msg_data), [](asio::error_code error) { if (error) { LOG(kWarning) << "rudp cannot send" << error.message(); } From a5f3eeeace20d4be8c3f868494759aecf379894d Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 17:58:00 +0100 Subject: [PATCH 17/72] Fixes invalid resialisation of the ConnectResponse message --- .../routing/messages/connect_response.h | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/maidsafe/routing/messages/connect_response.h b/src/maidsafe/routing/messages/connect_response.h index e66c574a..31c7f0b0 100644 --- a/src/maidsafe/routing/messages/connect_response.h +++ b/src/maidsafe/routing/messages/connect_response.h @@ -61,9 +61,25 @@ class ConnectResponse { ConnectResponse(const ConnectResponse&) = delete; ConnectResponse& operator=(const ConnectResponse&) = delete; + //template + //void serialize(Archive& archive) { + // archive(requester_endpoints_, receiver_endpoints_, requester_id_, receiver_id_, receiver_fob_); + //} + + template + void save(Archive& archive) const { + archive(requester_endpoints_, receiver_endpoints_, requester_id_, receiver_id_, + receiver_fob_.name(), receiver_fob_.Serialise()); + } + template - void serialize(Archive& archive) { - archive(requester_endpoints_, receiver_endpoints_, requester_id_, receiver_id_, receiver_fob_); + void load(Archive& archive) { + passport::PublicPmid::Name receiver_fob_name; + passport::PublicPmid::serialised_type receiver_fob_contents; + archive(requester_endpoints_, receiver_endpoints_, requester_id_, receiver_id_, + receiver_fob_name, receiver_fob_contents); + receiver_fob_ = + passport::PublicPmid(std::move(receiver_fob_name), std::move(receiver_fob_contents)); } EndpointPair requester_endpoints() const { return requester_endpoints_; } From fcdbceb29f4dd85be311f7bf2ee302bfc1761f13 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 4 Mar 2015 18:27:45 +0100 Subject: [PATCH 18/72] Fixes invalid serialisation of the Connect message --- src/maidsafe/routing/messages/connect.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/maidsafe/routing/messages/connect.h b/src/maidsafe/routing/messages/connect.h index bc9079db..29a1fcb8 100644 --- a/src/maidsafe/routing/messages/connect.h +++ b/src/maidsafe/routing/messages/connect.h @@ -58,9 +58,25 @@ class Connect { Connect(const Connect&) = default; Connect& operator=(const Connect&) = default; + //template + //void serialize(Archive& archive) { + // archive(requester_endpoints_, requester_id_, receiver_id_, requester_fob_); + //} + + template + void save(Archive& archive) const { + archive(requester_endpoints_, requester_id_, receiver_id_, + requester_fob_.name(), requester_fob_.Serialise()); + } + template - void serialize(Archive& archive) { - archive(requester_endpoints_, requester_id_, receiver_id_, requester_fob_); + void load(Archive& archive) { + passport::PublicPmid::Name receiver_fob_name; + passport::PublicPmid::serialised_type receiver_fob_contents; + archive(requester_endpoints_, requester_id_, receiver_id_, + receiver_fob_name, receiver_fob_contents); + requester_fob_ = + passport::PublicPmid(std::move(receiver_fob_name), std::move(receiver_fob_contents)); } EndpointPair requester_endpoints() const { return requester_endpoints_; } From 3f28b5635eacd12edeeadd80a3ae13a5a6b85e15 Mon Sep 17 00:00:00 2001 From: BSMaidSafe Date: Wed, 4 Mar 2015 17:35:13 +0000 Subject: [PATCH 19/72] Put/Get message handling and further testing. --- .../tests/routing_fake_vault_facade_test.cc | 35 +++++++----- .../routing/tests/utils/fake_vault_facade.cc | 36 +++++++++++++ .../routing/tests/utils/fake_vault_facade.h | 53 +++++++++++++++---- 3 files changed, 103 insertions(+), 21 deletions(-) diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index 61b2dade..a2c46b40 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -29,24 +29,35 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); } -TEST(RoutingFakeVaultFacadeTest, FUNC_Put) { - std::vector> vaults(3); +TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { + using endpoint = asio::ip::udp::endpoint; + using address = asio::ip::address_v4; + + std::vector> vaults(16); unsigned short port(5483); for (auto& vault : vaults) vault.second = port++; for (auto& vault : vaults) ASSERT_NO_THROW(vault.first.StartAccepting(vault.second)); - for (size_t i = 0; i != vaults.size(); ++i) { - for (size_t j = 0; j != vaults.size(); ++j) { - if (j > i) { - asio::ip::udp::endpoint endpoint(asio::ip::udp::v4(), vaults[j].second); - vaults[i].first.AddContact(endpoint); - } - } - } - Sleep(std::chrono::seconds(10)); - std::cout << "test end" << std::endl; + ASSERT_GE(vaults.size(), 2); + + for (size_t i = 0; i != vaults.size() - 1; ++i) + for (size_t j = i + 1; j != vaults.size(); ++j) + ASSERT_NO_THROW(vaults[j].first.AddContact(endpoint(address::loopback(), vaults[i].second))); + + auto vault_index(RandomUint32() % vaults.size()); + ImmutableData data(NonEmptyString(RandomAlphaNumericString(RandomUint32() % 1000))); + + vaults[vault_index].first.Put(NodeId(RandomString(NodeId::kSize)), data, + [](maidsafe_error error) { + ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); + }); + + vaults[vault_index].first.Get(data.name(), + [](maidsafe_error error) { + ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); + }); } } // namespace test diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index bb68fe3d..178044b9 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -24,6 +24,42 @@ namespace vault { namespace test { +template <> +ImmutableData ParseData(const SerialisedData& serialised_data) { + auto digest_size(crypto::SHA512::DIGESTSIZE); + std::string name(serialised_data.begin(), serialised_data.begin() + digest_size); + std::string content(serialised_data.begin() + digest_size, serialised_data.end()); + return ImmutableData(ImmutableData::Name(Identity(name)), + ImmutableData::serialised_type(NonEmptyString(content))); +} + +routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, + routing::Authority from_authority, routing::Authority authority, DataTagValue data_type, + SerialisedData serialised_data) { + switch (authority) { + case routing::Authority::client_manager: + if (from_authority != routing::Authority::client) + break; + if (data_type == DataTagValue::kImmutableDataValue) + return MaidManager::HandlePut(from, ParseData(serialised_data)); + else if (data_type == DataTagValue::kMutableDataValue) + return MaidManager::HandlePut(from, ParseData(serialised_data)); + else if (data_type == DataTagValue::kPmidValue) + return MaidManager::HandlePut(from, ParseData(serialised_data)); + case routing::Authority::nae_manager: + if (from_authority != routing::Authority::client_manager) + break; + if (data_type == DataTagValue::kImmutableDataValue) + return DataManager::HandlePut(from, ParseData(serialised_data)); + else if (data_type == DataTagValue::kMutableDataValue) + return DataManager::HandlePut(from, ParseData(serialised_data)); + break; + default: + break; + } + return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); +} + routing::HandleGetReturn FakeVaultFacade::HandleGet(routing::SourceAddress from, routing::Authority authority, DataTagValue data_type, Identity data_name) { switch (authority) { diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index 41263d90..2faf06fc 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -27,23 +27,55 @@ namespace vault { namespace test { +template +class MaidManager { + public: + MaidManager() {} + + template + routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); +}; + +template template +routing::HandlePutPostReturn MaidManager::HandlePut( + const routing::SourceAddress& /*source_address*/, const Data& data) { + std::vector result; + result.push_back(std::make_pair(routing::Destination(routing::Address(data.name())), + boost::none)); + return routing::HandlePutPostReturn(result); +} + + template class DataManager { public: DataManager() {} - template + template + routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); + template routing::HandleGetReturn HandleGet(const routing::SourceAddress& from, const Identity& name); private: + std::vector data_; routing::CloseGroupDifference close_group_; }; -template template +template template +routing::HandlePutPostReturn DataManager::HandlePut( + const routing::SourceAddress& /*from*/, const Data& data) { + if (std::find(std::begin(data_), std::end(data_), data.name().value.string()) == std::end(data_)) + data_.emplace_back(data.name().value.string()); + return boost::make_unexpected(MakeError(CommonErrors::success)); +} + +template template routing::HandleGetReturn DataManager::HandleGet( - const routing::SourceAddress& /*from*/, const Identity& /*name*/) { - std::cout << "DataManager::HandleGet called" << std::endl; - return routing::HandleGetReturn(); + const routing::SourceAddress& /*from*/, const Identity& name) { + auto it(std::find(std::begin(data_), std::end(data_), name.string())); + if (it != std::end(data_)) + return routing::HandleGetReturn(std::vector(it->begin(), it->end())); + return boost::make_unexpected(MakeError(CommonErrors::no_such_element)); } // Helper function to parse data name and contents @@ -57,17 +89,20 @@ ParsedType ParseData(const SerialisedData& serialised_data) { return ParsedType(name, contents); } -class FakeVaultFacade : public DataManager, +template <> +ImmutableData ParseData(const SerialisedData& serialised_data); + +class FakeVaultFacade : public MaidManager, + public DataManager, public routing::RoutingNode { public: FakeVaultFacade() - : DataManager(), + : MaidManager(), + DataManager(), routing::RoutingNode() {} ~FakeVaultFacade() = default; - enum class FunctorType { FunctionOne, FunctionTwo }; - void HandleConnectionAdded(routing::Address /*address*/) {} routing::HandleGetReturn HandleGet(routing::SourceAddress from, routing::Authority authority, From e013f5d9c4fdc0916728a38a45f8de0747c04394 Mon Sep 17 00:00:00 2001 From: BSMaidSafe Date: Fri, 6 Mar 2015 10:49:48 +0000 Subject: [PATCH 20/72] Minor change. --- src/maidsafe/routing/tests/utils/fake_vault_facade.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index 2faf06fc..f3b81fb7 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -19,6 +19,8 @@ #ifndef MAIDSAFE_ROUTING_TESTS_UTILS_FAKE_VAULT_FACADE_H_ #define MAIDSAFE_ROUTING_TESTS_UTILS_FAKE_VAULT_FACADE_H_ +#include + #include "maidsafe/routing/routing_node.h" namespace maidsafe { @@ -57,24 +59,24 @@ class DataManager { routing::HandleGetReturn HandleGet(const routing::SourceAddress& from, const Identity& name); private: - std::vector data_; + std::map data_; routing::CloseGroupDifference close_group_; }; template template routing::HandlePutPostReturn DataManager::HandlePut( const routing::SourceAddress& /*from*/, const Data& data) { - if (std::find(std::begin(data_), std::end(data_), data.name().value.string()) == std::end(data_)) - data_.emplace_back(data.name().value.string()); + if (data_.find(data.name().value.string()) == std::end(data_)) + data_.insert(std::make_pair(data.name().value.string(), data.data().string())); return boost::make_unexpected(MakeError(CommonErrors::success)); } template template routing::HandleGetReturn DataManager::HandleGet( const routing::SourceAddress& /*from*/, const Identity& name) { - auto it(std::find(std::begin(data_), std::end(data_), name.string())); + auto it(data_.find(name.string())); if (it != std::end(data_)) - return routing::HandleGetReturn(std::vector(it->begin(), it->end())); + return routing::HandleGetReturn(std::vector(it->second.begin(), it->second.end())); return boost::make_unexpected(MakeError(CommonErrors::no_such_element)); } From 6e675bdde2e237e0fb6365d0cca379018f26f8e7 Mon Sep 17 00:00:00 2001 From: prakash Date: Fri, 6 Mar 2015 16:47:51 +0000 Subject: [PATCH 21/72] minor updates --- include/maidsafe/routing/routing_node.h | 16 ++++-- src/maidsafe/routing/messages/messages.h | 54 ++++++++++++++++++++ src/maidsafe/routing/messages/messages_fwd.h | 52 ------------------- 3 files changed, 67 insertions(+), 55 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 97a7f77d..ecddf073 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -122,7 +122,7 @@ class RoutingNode { template void SendDirect(NodeId, Message, SendHandler); - EndpointPair NextEndpointPair() { // TODO(dirvine) :23/01/2015 + EndpointPair NextEndpointPair() { // FIXME(Peter) :06/03/2015 return EndpointPair(); } // this innocuous looking call will bootstrap the node and also be used if we spot close group @@ -330,8 +330,8 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, } // if we can satisfy request from cache we do if (tag == MessageTypeTag::GetData) { - auto data = Parse(binary_input_stream); - auto test = cache_.Get(data.name()); + auto get_data = Parse(binary_input_stream); + auto test = cache_.Get(get_data.name()); // FIXME(dirvine) move to upper lauer :09/02/2015 // if (test) { // GetDataResponse response(data.name(), test); @@ -367,7 +367,17 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, if (!connection_manager_.AddressInCloseGroupRange(header.Destination().first)) return; // not for us + // Drop message if it is a direct message type (Connect, ConnectResponse) and this node is in the + // group but the message destination is another group member node. + // Dropping this before Sentinel check + if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { + if (header.Destination() != connection_manager_.OurId()) // not for me + return; + } + // FIXME(dirvine) Sentinel check here!! :19/01/2015 + + switch (tag) { case MessageTypeTag::Connect: HandleMessage(Parse(binary_input_stream), std::move(header)); diff --git a/src/maidsafe/routing/messages/messages.h b/src/maidsafe/routing/messages/messages.h index 9204db36..210af13f 100644 --- a/src/maidsafe/routing/messages/messages.h +++ b/src/maidsafe/routing/messages/messages.h @@ -29,4 +29,58 @@ #include "maidsafe/routing/messages/put_data.h" #include "maidsafe/routing/messages/put_data_response.h" + +template +struct MessageToTag; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::Connect; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::ConnectResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::FindGroup; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::FindGroupResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::GetData; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::GetDataResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::PutData; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::PutDataResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::Post; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::PostResponse; } +}; + #endif // MAIDSAFE_ROUTING_MESSAGES_MESSAGES_H_ diff --git a/src/maidsafe/routing/messages/messages_fwd.h b/src/maidsafe/routing/messages/messages_fwd.h index e7f39e9b..fbd2a133 100644 --- a/src/maidsafe/routing/messages/messages_fwd.h +++ b/src/maidsafe/routing/messages/messages_fwd.h @@ -54,58 +54,6 @@ class PostResponse; class PutData; class PutDataResponse; -template -struct MessageToTag; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::Connect; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::ConnectResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::FindGroup; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::FindGroupResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::GetData; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::GetDataResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::PutData; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::PutDataResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::Post; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::PostResponse; } -}; } // namespace routing From 8514a513cc272671db4a8522bba56d674ecb8020 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 9 Mar 2015 16:46:43 +0000 Subject: [PATCH 22/72] moved connected nodes to connection manager. --- include/maidsafe/routing/routing_node.h | 21 ++++---- src/maidsafe/routing/connection_manager.cc | 16 +++++- src/maidsafe/routing/connection_manager.h | 11 +++- src/maidsafe/routing/messages/messages.h | 53 -------------------- src/maidsafe/routing/messages/messages_fwd.h | 53 ++++++++++++++++++++ 5 files changed, 88 insertions(+), 66 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index ecddf073..abc573ff 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -142,8 +142,6 @@ class RoutingNode { LruCache filter_; Sentinel sentinel_; LruCache cache_; - std::vector
connected_nodes_; - std::shared_ptr destroy_indicator_; }; @@ -157,11 +155,13 @@ RoutingNode::RoutingNode() connection_manager_(Address(our_fob_.name()->string()), [=](asio::error_code error, Address address, SerialisedMessage msg) { MessageReceived(error, std::move(address), std::move(msg)); + }, + [=](Address peer_id) { + ConnectionLost(peer_id); }), filter_(std::chrono::minutes(20)), sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), - connected_nodes_(), destroy_indicator_(new boost::none_t) { // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. @@ -357,10 +357,12 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, }); } // FIXME(dirvine) We need new rudp for this :26/01/2015 + std::vector
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; if (header.RelayedMessage() && - std::any_of(std::begin(connected_nodes_), std::end(connected_nodes_), + std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), [&header](const Address& node) { return node == *header.ReplyToAddress(); })) { // send message to connected node + connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); return; } @@ -371,7 +373,7 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, // group but the message destination is another group member node. // Dropping this before Sentinel check if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { - if (header.Destination() != connection_manager_.OurId()) // not for me + if (header.Destination().first != connection_manager_.OurId()) // not for me return; } @@ -432,11 +434,10 @@ Authority RoutingNode::OurAuthority(const Address& element, BOOST_THROW_EXCEPTION(MakeError(CommonErrors::invalid_parameter)); } -// TODO(PeterJ): -// template -// void RoutingNode::ConnectionLost(NodeId peer) { -// connection_manager_.LostNetworkConnection(peer); -// } +template +void RoutingNode::ConnectionLost(Address peer) { + connection_manager_.LostNetworkConnection(peer); +} // reply with our details; template diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index d3bbd2d0..b7d07895 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -43,11 +43,14 @@ using std::move; using boost::none_t; using boost::optional; -ConnectionManager::ConnectionManager(Address our_id, OnReceive on_receive) +ConnectionManager::ConnectionManager(Address our_id, OnReceive on_receive, + OnConnectionLost on_connection_lost) : mutex_(), boost_io_service_(1), routing_table_(our_id), + connected_non_routing_nodes_(), on_receive_(std::move(on_receive)), + on_connection_lost_(std::move(on_connection_lost)), current_close_group_(), connections_(new Connections(boost_io_service_.service(), our_id)) { StartReceiving(); @@ -65,6 +68,11 @@ std::vector ConnectionManager::GetTarget(const Address& target_node) c return nodes; } +std::vector
ConnectionManager::GetNonRoutingNodes() const { + std::lock_guard lock(mutex_); + return connected_non_routing_nodes_; +} + boost::optional ConnectionManager::LostNetworkConnection( const Address& node) { routing_table_.DropNode(node); @@ -184,6 +192,12 @@ void ConnectionManager::StartReceiving() { }); } +void ConnectionManager::SendToNonRoutingNode(const Address& /*addr*/, + const SerialisedMessage& /*message*/) { +// connections_->Send(addr, message, std::move(handler)); +// remove connection if failed +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 22918ae7..b8ef6354 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -64,9 +64,10 @@ class ConnectionManager { public: using OnReceive = std::function; using OnAddNode = std::function, Endpoint)>; + using OnConnectionLost = std::function; public: - ConnectionManager(Address our_id, OnReceive on_receive); + ConnectionManager(Address our_id, OnReceive on_receive, OnConnectionLost on_connection_lost); ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; @@ -76,6 +77,8 @@ class ConnectionManager { bool SuggestNodeToAdd(const Address& node_to_add) const; std::vector GetTarget(const Address& target_node) const; + std::vector
GetNonRoutingNodes() const; + boost::optional LostNetworkConnection(const Address& node); // routing wishes to drop a specific node (may be a node we cannot connect to) @@ -112,6 +115,8 @@ class ConnectionManager { template void Send(const Address&, const SerialisedMessage&, Handler); + void SendToNonRoutingNode(const Address&, const SerialisedMessage&); // remove connection if fails + template void Connect(asio::ip::udp::endpoint, Handler); @@ -122,10 +127,12 @@ class ConnectionManager { private: boost::optional GroupChanged(); - std::mutex mutex_; + mutable std::mutex mutex_; BoostAsioService boost_io_service_; RoutingTable routing_table_; + std::vector
connected_non_routing_nodes_; // clients & bootstrapping nodes OnReceive on_receive_; + OnConnectionLost on_connection_lost_; std::vector
current_close_group_; std::function group_changed_functor_; std::shared_ptr connections_; diff --git a/src/maidsafe/routing/messages/messages.h b/src/maidsafe/routing/messages/messages.h index 210af13f..fd0bc3a8 100644 --- a/src/maidsafe/routing/messages/messages.h +++ b/src/maidsafe/routing/messages/messages.h @@ -30,57 +30,4 @@ #include "maidsafe/routing/messages/put_data_response.h" -template -struct MessageToTag; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::Connect; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::ConnectResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::FindGroup; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::FindGroupResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::GetData; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::GetDataResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::PutData; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::PutDataResponse; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::Post; } -}; - -template <> -struct MessageToTag { - static MessageTypeTag value() { return MessageTypeTag::PostResponse; } -}; - #endif // MAIDSAFE_ROUTING_MESSAGES_MESSAGES_H_ diff --git a/src/maidsafe/routing/messages/messages_fwd.h b/src/maidsafe/routing/messages/messages_fwd.h index fbd2a133..771264a5 100644 --- a/src/maidsafe/routing/messages/messages_fwd.h +++ b/src/maidsafe/routing/messages/messages_fwd.h @@ -54,6 +54,59 @@ class PostResponse; class PutData; class PutDataResponse; +template +struct MessageToTag; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::Connect; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::ConnectResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::FindGroup; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::FindGroupResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::GetData; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::GetDataResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::PutData; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::PutDataResponse; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::Post; } +}; + +template <> +struct MessageToTag { + static MessageTypeTag value() { return MessageTypeTag::PostResponse; } +}; + } // namespace routing From a68de33de454cbf8f0f479230bcb4de08459e938 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 9 Mar 2015 17:24:41 +0000 Subject: [PATCH 23/72] minor update --- include/maidsafe/routing/routing_node.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index abc573ff..ae698453 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -436,7 +436,9 @@ Authority RoutingNode::OurAuthority(const Address& element, template void RoutingNode::ConnectionLost(Address peer) { - connection_manager_.LostNetworkConnection(peer); + auto change = connection_manager_.LostNetworkConnection(peer); + if (change) + static_cast(this)->HandleChurn(*added); } // reply with our details; From 5ef3f9754103c4a84253d83606f796e96bbbd418 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Mon, 9 Mar 2015 22:38:31 +0100 Subject: [PATCH 24/72] Connections class now supports asio::async_result Also adds test for it --- include/maidsafe/routing/types.h | 9 ++ src/maidsafe/routing/async_exchange.h | 4 +- src/maidsafe/routing/connection_manager.cc | 17 +-- src/maidsafe/routing/connections.h | 137 ++++++++++++------ .../routing/tests/routing_connections_test.cc | 71 +++++++-- 5 files changed, 171 insertions(+), 67 deletions(-) diff --git a/include/maidsafe/routing/types.h b/include/maidsafe/routing/types.h index 8cb23510..9a78d4cb 100644 --- a/include/maidsafe/routing/types.h +++ b/include/maidsafe/routing/types.h @@ -92,6 +92,15 @@ using Checksum = crypto::SHA1Hash; using CloseGroupDifference = std::pair, std::vector
>; +template +using AsyncResultHandler = + typename asio::handler_type::type, void(asio::error_code, Args...)>::type; + +template +using AsyncResultReturn = + typename asio::async_result>::type; + +// FIXME: All the below handlers and results can be implemented using the above two. template using BootstrapHandlerHandler = typename asio::handler_type::type; diff --git a/src/maidsafe/routing/async_exchange.h b/src/maidsafe/routing/async_exchange.h index 1fe159a3..36868558 100644 --- a/src/maidsafe/routing/async_exchange.h +++ b/src/maidsafe/routing/async_exchange.h @@ -46,7 +46,7 @@ void AsyncExchange(crux::socket& socket, SerialisedMessage our_data, Handler han state->tx_buffer = std::move(our_data); socket.async_send(boost::asio::buffer(state->tx_buffer), - [state, handler](boost::system::error_code error, std::size_t) { + [state, handler](boost::system::error_code error, std::size_t) mutable { if (state->first_error) { if (*state->first_error) { return handler(*state->first_error, SerialisedMessage()); @@ -61,7 +61,7 @@ void AsyncExchange(crux::socket& socket, SerialisedMessage our_data, Handler han }); socket.async_receive(boost::asio::buffer(state->rx_buffer), - [state, handler](boost::system::error_code error, std::size_t size) { + [state, handler](boost::system::error_code error, std::size_t size) mutable { if (state->first_error) { if (*state->first_error) { return handler(*state->first_error, SerialisedMessage()); diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index d3bbd2d0..1fd35061 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -87,16 +87,16 @@ void ConnectionManager::AddNode( // TODO(PeterJ): Use local endpoint as well connections_->Connect(their_endpoint_pair.external, - [=](asio::error_code error, Address addr, Endpoint our_endpoint) { + [=](asio::error_code error, Connections::ConnectResult result) { if (!weak_connections.lock()) { return; } - if (error || (addr != node_to_add.id)) { + if (error || (result.his_address != node_to_add.id)) { return; } - on_node_added(AddToRoutingTable(node_to_add), our_endpoint); + on_node_added(AddToRoutingTable(node_to_add), result.our_endpoint); }); } @@ -111,19 +111,19 @@ template void StartAccepting(std::weak_ptr weak_conn // TODO(Team): What endpoint should we accept on? connections->Accept(6378, - [=](asio::error_code error, asio::ip::udp::endpoint, Address addr, Endpoint our_endpoint) { + [=](asio::error_code error, Connections::AcceptResult result) { if (error) { return; } - if (node_to_add.id != addr) { + if (node_to_add.id != result.his_address) { // Restart StartAccepting(weak_connections, std::move(node_to_add), std::move(node_eps), std::move(handler)); return; } - handler(our_endpoint); + handler(result.our_endpoint); }); } @@ -173,11 +173,10 @@ boost::optional ConnectionManager::GroupChanged() { void ConnectionManager::StartReceiving() { std::weak_ptr weak_connections = connections_; - connections_->Receive([=](asio::error_code error, Address address, - const SerialisedMessage& message) { + connections_->Receive([=](asio::error_code error, Connections::ReceiveResult result) { if (!weak_connections.lock()) return; auto h = std::move(on_receive_); - h(error, std::move(address), std::move(message)); + h(error, std::move(result.his_address), std::move(result.message)); if (!weak_connections.lock()) return; on_receive_ = std::move(h); StartReceiving(); diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 95a3e5a5..7704b885 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -42,6 +42,23 @@ namespace maidsafe { namespace routing { class Connections { + public: + struct AcceptResult { + Endpoint his_endpoint; + Address his_address; + Endpoint our_endpoint; // As seen by the other end + }; + + struct ConnectResult { + Address his_address; + Endpoint our_endpoint; // As seen by the other end + }; + + struct ReceiveResult { + Address his_address; + SerialisedMessage message; + }; + public: Connections(boost::asio::io_service&, const Address& our_node_id); @@ -54,17 +71,17 @@ class Connections { ~Connections(); - template - void Send(const Address&, const SerialisedMessage&, Handler); + template + AsyncResultReturn Send(const Address&, const SerialisedMessage&, Token&&); - template - void Receive(Handler); + template + AsyncResultReturn Receive(Token&&); - template - void Connect(asio::ip::udp::endpoint, Handler); + template + AsyncResultReturn Connect(asio::ip::udp::endpoint, Token&&); - template - void Accept(unsigned short port, const Handler); + template + AsyncResultReturn Accept(unsigned short port, Token&&); void Drop(const Address& their_id); @@ -90,15 +107,20 @@ class Connections { std::map> connections_; std::map id_to_endpoint_map_; - AsyncQueue receive_queue_; + AsyncQueue receive_queue_; }; inline Connections::Connections(boost::asio::io_service& ios, const Address& our_node_id) : service_(ios), our_id_(our_node_id) {} -template -void Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, Handler handler) { - service_.post([=]() { +template +AsyncResultReturn Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, + Token&& token) { + using Handler = AsyncResultHandler; + Handler handler(std::forward(token)); + asio::async_result result(handler); + + get_io_service().post([=]() mutable { auto remote_endpoint_i = id_to_endpoint_map_.find(remote_id); if (remote_endpoint_i == id_to_endpoint_map_.end()) { @@ -115,7 +137,7 @@ void Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, std::weak_ptr weak_socket = socket; socket->async_send(boost::asio::buffer(*buffer), - [=](boost::system::error_code error, std::size_t) { + [=](boost::system::error_code error, std::size_t) mutable { static_cast(buffer); if (!weak_socket.lock()) { @@ -128,39 +150,57 @@ void Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, handler(convert::ToStd(error)); }); }); + + return result.get(); } -template -void Connections::Receive(Handler handler) { - service_.post([=]() { receive_queue_.AsyncPop(std::move(handler)); }); +template +AsyncResultReturn Connections::Receive(Token&& token) { + using Handler = AsyncResultHandler; + Handler handler(std::forward(token)); + asio::async_result result(handler); + + // TODO(PeterJ): For some reason I need to wrap the handler, otherwise I get crashes + // in the future tests. + auto handler2 = [=](asio::error_code error, ReceiveResult result) mutable { + handler(error, std::move(result)); + }; + + get_io_service().post([=]() mutable { receive_queue_.AsyncPop(handler2); }); + + return result.get(); } inline Connections::~Connections() { Shutdown(); } -template -void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { - using asio_endpoint = asio::ip::udp::endpoint; +template +AsyncResultReturn Connections::Connect(Endpoint endpoint, + Token&& token) { - service_.post([=]() { + using Handler = AsyncResultHandler; + Handler handler(std::forward(token)); + asio::async_result result(handler); + + get_io_service().post([=]() mutable { crux::endpoint unspecified_ep(boost::asio::ip::udp::v4(), 0); auto socket = std::make_shared(service_, unspecified_ep); auto insert_result = connections_.insert(std::make_pair(convert::ToBoost(endpoint), socket)); if (!insert_result.second) { - return handler(asio::error::already_started, Address(), asio_endpoint()); + return handler(asio::error::already_started, ConnectResult()); } std::weak_ptr weak_socket = socket; - socket->async_connect(convert::ToBoost(endpoint), [=](boost::system::error_code error) { + socket->async_connect(convert::ToBoost(endpoint), [=](boost::system::error_code error) mutable { auto socket = weak_socket.lock(); if (!socket) { - return handler(asio::error::operation_aborted, Address(), asio_endpoint()); + return handler(asio::error::operation_aborted, ConnectResult()); } if (error) { - return handler(convert::ToStd(error), Address(), asio_endpoint()); + return handler(convert::ToStd(error), ConnectResult()); } auto remote_endpoint = socket->remote_endpoint(); @@ -169,16 +209,16 @@ void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { auto his_endpoint = convert::ToAsio(socket->remote_endpoint()); AsyncExchange(*socket, Serialise(our_id_, his_endpoint), - [=](boost::system::error_code error, SerialisedMessage data) { + [=](boost::system::error_code error, SerialisedMessage data) mutable { auto socket = weak_socket.lock(); if (!socket) { - return handler(asio::error::operation_aborted, Address(), asio_endpoint()); + return handler(asio::error::operation_aborted, ConnectResult()); } if (error) { connections_.erase(remote_endpoint); - return handler(convert::ToStd(error), Address(), asio_endpoint()); + return handler(convert::ToStd(error), ConnectResult()); } InputVectorStream stream(data); @@ -189,15 +229,22 @@ void Connections::Connect(asio::ip::udp::endpoint endpoint, Handler handler) { id_to_endpoint_map_[his_id] = remote_endpoint; StartReceiving(his_id, remote_endpoint, socket); - handler(convert::ToStd(error), his_id, our_endpoint); + handler(convert::ToStd(error), ConnectResult{his_id, our_endpoint}); }); }); }); + + return result.get(); } -template -void Connections::Accept(unsigned short port, const Handler handler) { - service_.post([=]() { +template +AsyncResultReturn Connections::Accept(unsigned short port, + Token&& token) { + using Handler = AsyncResultHandler; + Handler handler(std::forward(token)); + asio::async_result result(handler); + + get_io_service().post([=]() mutable { auto find_result = acceptors_.insert(std::make_pair(port, std::shared_ptr())); auto& acceptor = find_result.first->second; @@ -211,13 +258,13 @@ void Connections::Accept(unsigned short port, const Handler handler) { auto socket = std::make_shared(service_); - acceptor->async_accept(*socket, [=](boost::system::error_code error) { + acceptor->async_accept(*socket, [=](boost::system::error_code error) mutable { if (!weak_acceptor.lock()) { - return handler(asio::error::operation_aborted, Endpoint(), Address(), Endpoint()); + return handler(asio::error::operation_aborted, AcceptResult()); } if (error) { - return handler(asio::error::operation_aborted, Endpoint(), Address(), Endpoint()); + return handler(asio::error::operation_aborted, AcceptResult()); } acceptors_.erase(port); @@ -228,18 +275,18 @@ void Connections::Accept(unsigned short port, const Handler handler) { std::weak_ptr weak_socket = socket; AsyncExchange(*socket, Serialise(our_id_, his_endpoint), [=](boost::system::error_code error, - SerialisedMessage data) { + SerialisedMessage data) mutable { auto socket = weak_socket.lock(); if (!socket) { - return handler(asio::error::operation_aborted, convert::ToAsio(remote_endpoint), - Address(), Endpoint()); + return handler(asio::error::operation_aborted, + AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); } if (error) { connections_.erase(remote_endpoint); - return handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), Address(), - Endpoint()); + return handler(convert::ToStd(error), + AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); } InputVectorStream stream(data); @@ -250,10 +297,13 @@ void Connections::Accept(unsigned short port, const Handler handler) { id_to_endpoint_map_[his_id] = remote_endpoint; StartReceiving(his_id, remote_endpoint, socket); - handler(convert::ToStd(error), convert::ToAsio(remote_endpoint), his_id, our_endpoint); + handler(convert::ToStd(error), + AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); }); }); }); + + return result.get(); } inline void Connections::StartReceiving(const Address& id, const crux::endpoint& remote_endpoint, @@ -264,11 +314,12 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& auto buffer = std::make_shared(max_message_size()); socket->async_receive( - boost::asio::buffer(*buffer), [=](boost::system::error_code error, size_t size) { + boost::asio::buffer(*buffer), [=](boost::system::error_code error, size_t size) mutable { auto socket = weak_socket.lock(); if (!socket) { - return receive_queue_.Push(asio::error::operation_aborted, id, std::move(*buffer)); + return receive_queue_.Push(asio::error::operation_aborted, + ReceiveResult{id, std::move(*buffer)}); } if (error) { @@ -277,7 +328,7 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& } buffer->resize(size); - receive_queue_.Push(convert::ToStd(error), id, std::move(*buffer)); + receive_queue_.Push(convert::ToStd(error), ReceiveResult{id, std::move(*buffer)}); if (error) return; diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc index af912796..cdfd8953 100644 --- a/src/maidsafe/routing/tests/routing_connections_test.cc +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -17,6 +17,8 @@ use of the MaidSafe Software. */ +#include "asio/use_future.hpp" + #include "maidsafe/common/test.h" #include "maidsafe/common/utils.h" @@ -29,6 +31,14 @@ namespace routing { namespace test { +static SerialisedMessage str_to_msg(const std::string& str) { + return SerialisedMessage(str.begin(), str.end()); +} + +static std::string msg_to_str(const SerialisedMessage& msg) { + return std::string(msg.begin(), msg.end()); +} + TEST(ConnectionsTest, FUNC_TwoConnections) { boost::asio::io_service ios; @@ -44,14 +54,13 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { bool c2_finished = false; c1.Accept(port, - [&](asio::error_code error, asio::ip::udp::endpoint, NodeId his_id, Endpoint my_ep) { + [&](asio::error_code error, Connections::AcceptResult result) { ASSERT_FALSE(error); - ASSERT_EQ(his_id, c2.OurId()); - ASSERT_EQ(my_ep.port(), port); - std::string msg = "hello"; + ASSERT_EQ(result.his_address, c2.OurId()); + ASSERT_EQ(result.our_endpoint.port(), port); - c1.Send(his_id, - std::vector(msg.begin(), msg.end()), + c1.Send(result.his_address, + str_to_msg("hello"), [&](asio::error_code error) { ASSERT_FALSE(error); c1.Shutdown(); @@ -60,16 +69,14 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { }); c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), - [&](asio::error_code error, NodeId his_id, Endpoint /*my_ep*/) { + [&](asio::error_code error, Connections::ConnectResult result) { ASSERT_FALSE(error); - ASSERT_EQ(his_id, c1.OurId()); + ASSERT_EQ(result.his_address, c1.OurId()); - c2.Receive([&, his_id](asio::error_code error, - NodeId sender_id, - const std::vector& bytes) { + c2.Receive([&, result](asio::error_code error, Connections::ReceiveResult recv_result) { ASSERT_FALSE(error); - ASSERT_EQ(sender_id, his_id); - ASSERT_EQ(std::string(bytes.begin(), bytes.end()), "hello"); + ASSERT_EQ(recv_result.his_address, result.his_address); + ASSERT_EQ(msg_to_str(recv_result.message), "hello"); c2.Shutdown(); c2_finished = true; @@ -81,6 +88,44 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { ASSERT_TRUE(c1_finished && c2_finished); } +TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { + boost::asio::io_service ios; + boost::asio::io_service::work work(ios); + + NodeId c1_id(NodeId(RandomString(NodeId::kSize))); + NodeId c2_id(NodeId(RandomString(NodeId::kSize))); + + Connections c1(ios, c1_id); + Connections c2(ios, c2_id); + + unsigned short port = 8080; + + std::thread thread([&]() { ios.run(); }); + + auto accept_f = c1.Accept(port, asio::use_future); + auto connect_f = c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), asio::use_future); + + auto accept_result = accept_f.get(); + auto connect_result = connect_f.get(); + + ASSERT_EQ(accept_result.his_address, c2.OurId()); + ASSERT_EQ(accept_result.our_endpoint.port(), port); + + ASSERT_EQ(connect_result.his_address, c1.OurId()); + + auto recv_f = c2.Receive(asio::use_future); + auto send_f = c1.Send(accept_result.his_address, str_to_msg("hello"), asio::use_future); + + send_f.get(); + recv_f.get(); + + c1.Shutdown(); + c2.Shutdown(); + + ios.stop(); + thread.join(); +} + } // namespace test } // namespace routing From 25011358bc77b3b58f22eddd656f1c350bf3b7fc Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 11 Mar 2015 13:43:26 +0100 Subject: [PATCH 25/72] Fixes a compilation problem --- src/maidsafe/routing/connection_manager.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index b8ef6354..ed9f3eb2 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -146,7 +146,10 @@ void ConnectionManager::Send(const Address& addr, const SerialisedMessage& messa template void ConnectionManager::Connect(asio::ip::udp::endpoint remote_endpoint, Handler handler) { - connections_->Connect(remote_endpoint, std::move(handler)); + connections_->Connect(remote_endpoint, [=](asio::error_code error, + Connections::ConnectResult result) { + handler(error, result.his_address, result.our_endpoint); + }); } } // namespace routing From 567b28e329d2a7f0c231311a75449269d40921c7 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Thu, 12 Mar 2015 00:04:42 +0100 Subject: [PATCH 26/72] Refactores acceptation of new connections Validated and non validated connections are now accepted through only one handler. Also acceptation starts on the 5483 port and if it is already taken a random port is chosen. --- include/maidsafe/routing/routing_node.h | 35 +------ src/maidsafe/routing/connection_manager.cc | 92 ++++++++++++------- src/maidsafe/routing/connection_manager.h | 19 +++- src/maidsafe/routing/connections.h | 38 ++++++-- .../routing/tests/routing_connections_test.cc | 4 +- 5 files changed, 111 insertions(+), 77 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index ae698453..e3f56ccb 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -166,19 +166,6 @@ RoutingNode::RoutingNode() // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); - // try an connect to any local nodes (5483) Expect to be told Node_Id - auto temp_id(Address(RandomString(Address::kSize))); - // PeterJ: Start listening on ports 5483 and 5433 (why two though?) - // rudp_.Add(rudp::Contact(temp_id, EndpointPair{rudp::Endpoint{GetLocalIp(), 5483}, - // rudp::Endpoint{GetLocalIp(), 5433}}, - // our_fob_.public_key()), - // [this, temp_id](asio::error_code error) { - // if (!error) { - // bootstrap_node_ = temp_id; - // ConnectToCloseGroup(); - // return; - // } - // }); auto bootstrap_contacts = bootstrap_handler_.ReadBootstrapContacts(); @@ -197,18 +184,6 @@ RoutingNode::RoutingNode() ConnectToCloseGroup(); }); } - - // for (auto& node : bootstrap_handler_.ReadBootstrapContacts()) { - // rudp_.Add(node, [node, this](asio::error_code error) { - // if (!error) { - // bootstrap_node_ = node.id; - // ConnectToCloseGroup(); - // return; - // } - // }); - // if (bootstrap_node_) - // break; - // } } template @@ -357,7 +332,7 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, }); } // FIXME(dirvine) We need new rudp for this :26/01/2015 - std::vector
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; + std::set
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; if (header.RelayedMessage() && std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), [&header](const Address& node) { return node == *header.ReplyToAddress(); })) { @@ -435,10 +410,10 @@ Authority RoutingNode::OurAuthority(const Address& element, } template -void RoutingNode::ConnectionLost(Address peer) { - auto change = connection_manager_.LostNetworkConnection(peer); - if (change) - static_cast(this)->HandleChurn(*added); +void RoutingNode::ConnectionLost(Address /*peer*/) { + //auto change = connection_manager_.LostNetworkConnection(peer); + //if (change) + // static_cast(this)->HandleChurn(*added); } // reply with our details; diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index f7fdab44..e97a6e62 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -46,6 +46,7 @@ using boost::optional; ConnectionManager::ConnectionManager(Address our_id, OnReceive on_receive, OnConnectionLost on_connection_lost) : mutex_(), + our_accept_port_(5483), boost_io_service_(1), routing_table_(our_id), connected_non_routing_nodes_(), @@ -54,6 +55,7 @@ ConnectionManager::ConnectionManager(Address our_id, OnReceive on_receive, current_close_group_(), connections_(new Connections(boost_io_service_.service(), our_id)) { StartReceiving(); + StartAccepting(); } bool ConnectionManager::SuggestNodeToAdd(const Address& node_to_add) const { @@ -68,7 +70,7 @@ std::vector ConnectionManager::GetTarget(const Address& target_node) c return nodes; } -std::vector
ConnectionManager::GetNonRoutingNodes() const { +std::set
ConnectionManager::GetNonRoutingNodes() const { std::lock_guard lock(mutex_); return connected_non_routing_nodes_; } @@ -88,58 +90,80 @@ void ConnectionManager::DropNode(const Address& their_id) { connections_->Drop(their_id); } -void ConnectionManager::AddNode( - NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode on_node_added) { - +void ConnectionManager::StartAccepting() { std::weak_ptr weak_connections = connections_; - // TODO(PeterJ): Use local endpoint as well - connections_->Connect(their_endpoint_pair.external, - [=](asio::error_code error, Connections::ConnectResult result) { - if (!weak_connections.lock()) { + auto accept_handler = [=](asio::error_code error, Connections::AcceptResult result) { + auto connections = weak_connections.lock(); + + if (!connections) { return; } - if (error || (result.his_address != node_to_add.id)) { + if (error == asio::error::operation_aborted || error == asio::error::already_started) { return; } - on_node_added(AddToRoutingTable(node_to_add), result.our_endpoint); - }); -} + if (!error) { + OnAccept(std::move(result)); -template void StartAccepting(std::weak_ptr weak_connections, - NodeInfo node_to_add, EndpointPair node_eps, - Handler handler) { - auto connections = weak_connections.lock(); + // The handler may have destroyed 'this'. + if (!weak_connections.lock()) { + return; + } + } - if (!connections) { - return; - } + return StartAccepting(); + }; - // TODO(Team): What endpoint should we accept on? - connections->Accept(6378, - [=](asio::error_code error, Connections::AcceptResult result) { - if (error) { - return; - } + connections_->Accept(our_accept_port_, &our_accept_port_, std::move(accept_handler)); +} + +void ConnectionManager::OnAccept(Connections::AcceptResult result) { + auto expected_i = expected_accepts_.find(result.his_endpoint); - if (node_to_add.id != result.his_address) { - // Restart - StartAccepting(weak_connections, std::move(node_to_add), std::move(node_eps), - std::move(handler)); + if (expected_i != expected_accepts_.end()) { + if (expected_i->second.node_info.id != result.his_address) { return; } - handler(result.our_endpoint); - }); + auto expected = std::move(expected_i->second); + expected_accepts_.erase(expected_i); + + expected.handler(AddToRoutingTable(std::move(expected.node_info)), result.our_endpoint); + } + else { + connected_non_routing_nodes_.insert(result.his_address); + } } -void ConnectionManager::AddNodeAccept(NodeInfo node_to_add, EndpointPair their_endpoint_pair, +void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair his_endpoint_pair, OnAddNode on_node_added) { + // TODO(PeterJ): Use internal endpoint as well. + expected_accepts_.insert(std::make_pair(his_endpoint_pair.external, + ExpectedAccept{node_info, on_node_added})); + //StartAccepting(connections_, node_to_add, their_endpoint_pair, [=](Endpoint our_endpoint) { + // on_node_added(AddToRoutingTable(node_to_add), our_endpoint); + //}); +} + +void ConnectionManager::AddNode( + NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode on_node_added) { + + std::weak_ptr weak_connections = connections_; + + // TODO(PeterJ): Use local endpoint as well + connections_->Connect(their_endpoint_pair.external, + [=](asio::error_code error, Connections::ConnectResult result) { + if (!weak_connections.lock()) { + return; + } - StartAccepting(connections_, node_to_add, their_endpoint_pair, [=](Endpoint our_endpoint) { - on_node_added(AddToRoutingTable(node_to_add), our_endpoint); + if (error || (result.his_address != node_to_add.id)) { + return; + } + + on_node_added(AddToRoutingTable(node_to_add), result.our_endpoint); }); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index ed9f3eb2..cd378382 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -66,6 +66,12 @@ class ConnectionManager { using OnAddNode = std::function, Endpoint)>; using OnConnectionLost = std::function; + private: + struct ExpectedAccept { + NodeInfo node_info; + OnAddNode handler; + }; + public: ConnectionManager(Address our_id, OnReceive on_receive, OnConnectionLost on_connection_lost); @@ -77,7 +83,7 @@ class ConnectionManager { bool SuggestNodeToAdd(const Address& node_to_add) const; std::vector GetTarget(const Address& target_node) const; - std::vector
GetNonRoutingNodes() const; + std::set
GetNonRoutingNodes() const; boost::optional LostNetworkConnection(const Address& node); @@ -117,24 +123,33 @@ class ConnectionManager { void SendToNonRoutingNode(const Address&, const SerialisedMessage&); // remove connection if fails + unsigned short AcceptingPort() const { return our_accept_port_; } + + boost::asio::io_service& get_io_service() { return boost_io_service_.service(); } + template void Connect(asio::ip::udp::endpoint, Handler); private: boost::optional AddToRoutingTable(NodeInfo node_to_add); void StartReceiving(); + void StartAccepting(); + + void OnAccept(Connections::AcceptResult); private: boost::optional GroupChanged(); mutable std::mutex mutex_; + unsigned short our_accept_port_; BoostAsioService boost_io_service_; RoutingTable routing_table_; - std::vector
connected_non_routing_nodes_; // clients & bootstrapping nodes + std::set
connected_non_routing_nodes_; // clients & bootstrapping nodes OnReceive on_receive_; OnConnectionLost on_connection_lost_; std::vector
current_close_group_; std::function group_changed_functor_; + std::map expected_accepts_; std::shared_ptr connections_; }; diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 7704b885..04d77e31 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -80,8 +80,11 @@ class Connections { template AsyncResultReturn Connect(asio::ip::udp::endpoint, Token&&); + // The secont argument is an ugly C-style return of the actual port that has been + // chosen. TODO: Try to return it using a proper C++ way. template - AsyncResultReturn Accept(unsigned short port, Token&&); + AsyncResultReturn + Accept(unsigned short port, unsigned short* chosen_port, Token&&); void Drop(const Address& their_id); @@ -238,20 +241,37 @@ AsyncResultReturn Connections::Connect(Endpoi } template -AsyncResultReturn Connections::Accept(unsigned short port, - Token&& token) { +AsyncResultReturn +Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& token) { + using Handler = AsyncResultHandler; Handler handler(std::forward(token)); asio::async_result result(handler); - get_io_service().post([=]() mutable { - auto find_result = acceptors_.insert(std::make_pair(port, std::shared_ptr())); + + auto loopback = [](unsigned short port) { + return crux::endpoint(boost::asio::ip::udp::v4(), port); + }; + + // TODO(PeterJ):Make sure this operation is thread safe in crux. + std::shared_ptr acceptor; - auto& acceptor = find_result.first->second; + try { + acceptor = std::make_shared(service_, loopback(port)); + } + catch(...) { + acceptor = std::make_shared(service_, loopback(0)); + } + + if (chosen_port) { + *chosen_port = acceptor->local_endpoint().port(); + } + + get_io_service().post([=]() mutable { + auto find_result = acceptors_.insert(std::make_pair(port, acceptor)); - if (!acceptor) { - crux::endpoint endpoint(boost::asio::ip::udp::v4(), port); - acceptor.reset(new crux::acceptor(service_, endpoint)); + if (!find_result.second /* inserted? */) { + return handler(asio::error::already_started, Connections::AcceptResult()); } std::weak_ptr weak_acceptor = acceptor; diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc index cdfd8953..144867f1 100644 --- a/src/maidsafe/routing/tests/routing_connections_test.cc +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -53,7 +53,7 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { bool c1_finished = false; bool c2_finished = false; - c1.Accept(port, + c1.Accept(port, nullptr, [&](asio::error_code error, Connections::AcceptResult result) { ASSERT_FALSE(error); ASSERT_EQ(result.his_address, c2.OurId()); @@ -102,7 +102,7 @@ TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { std::thread thread([&]() { ios.run(); }); - auto accept_f = c1.Accept(port, asio::use_future); + auto accept_f = c1.Accept(port, nullptr, asio::use_future); auto connect_f = c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), asio::use_future); auto accept_result = accept_f.get(); From bc023380d16048e95bfa3fc50df9a1a8b14d9825 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Thu, 12 Mar 2015 12:46:19 +0100 Subject: [PATCH 27/72] NextEndpointPair now returns an endpoint we're accepting on --- include/maidsafe/routing/routing_node.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index e3f56ccb..125f44cb 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -123,7 +123,12 @@ class RoutingNode { template void SendDirect(NodeId, Message, SendHandler); EndpointPair NextEndpointPair() { // FIXME(Peter) :06/03/2015 - return EndpointPair(); + if (!our_external_endpoint_) { + return EndpointPair(); + } + return EndpointPair(Endpoint(asio::ip::address_v4::loopback(), + our_external_endpoint_->port()), + *our_external_endpoint_); } // this innocuous looking call will bootstrap the node and also be used if we spot close group // nodes appering or vanishing so its pretty important. @@ -136,7 +141,7 @@ class RoutingNode { passport::Pmid our_fob_; std::atomic message_id_; boost::optional
bootstrap_node_; - boost::optional bootstrap_endpoint_; + boost::optional our_external_endpoint_; BootstrapHandler bootstrap_handler_; ConnectionManager connection_manager_; LruCache filter_; @@ -180,7 +185,8 @@ RoutingNode::RoutingNode() } // FIXME(Team): Thread safety. bootstrap_node_ = contact.id; - bootstrap_endpoint_ = our_endpoint; + our_external_endpoint_ = Endpoint(our_endpoint.address(), + connection_manager_.AcceptingPort()); ConnectToCloseGroup(); }); } From 4ea6da7a163f2bc846ff4aa1d790114722966696 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Thu, 12 Mar 2015 17:06:15 +0100 Subject: [PATCH 28/72] Propagate connection lost information up from ConnectionManager --- include/maidsafe/routing/routing_node.h | 21 +++++++++--------- src/maidsafe/routing/connection_manager.cc | 25 +++++++++++++++------- src/maidsafe/routing/connection_manager.h | 24 +++++++++++++++------ src/maidsafe/routing/connections.h | 9 +++++++- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 125f44cb..28a550fd 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -112,8 +112,8 @@ class RoutingNode { void HandleMessage(routing::Post post, MessageHeader original_header); bool TryCache(MessageTypeTag tag, MessageHeader header, Address name); Authority OurAuthority(const Address& element, const MessageHeader& header) const; - void MessageReceived(asio::error_code, Address peer_id, SerialisedMessage serialised_message); - void ConnectionLost(Address peer); + void MessageReceived(Address peer_id, SerialisedMessage serialised_message); + void ConnectionLost(boost::optional, Address peer); void OnCloseGroupChanged(CloseGroupDifference close_group_difference); SourceAddress OurSourceAddress() const; SourceAddress OurSourceAddress(GroupAddress) const; @@ -158,11 +158,11 @@ RoutingNode::RoutingNode() bootstrap_node_(boost::none), bootstrap_handler_(), connection_manager_(Address(our_fob_.name()->string()), - [=](asio::error_code error, Address address, SerialisedMessage msg) { - MessageReceived(error, std::move(address), std::move(msg)); + [=](Address address, SerialisedMessage msg) { + MessageReceived(std::move(address), std::move(msg)); }, - [=](Address peer_id) { - ConnectionLost(peer_id); + [=](boost::optional diff, Address peer_id) { + ConnectionLost(std::move(diff), std::move(peer_id)); }), filter_(std::chrono::minutes(20)), sentinel_(asio_service_.service()), @@ -284,8 +284,7 @@ void RoutingNode::ConnectToCloseGroup() { } template -void RoutingNode::MessageReceived(asio::error_code /*error*/, - NodeId /* peer_id */, +void RoutingNode::MessageReceived(NodeId /* peer_id */, SerialisedMessage serialised_message) { InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; @@ -416,10 +415,10 @@ Authority RoutingNode::OurAuthority(const Address& element, } template -void RoutingNode::ConnectionLost(Address /*peer*/) { +void RoutingNode::ConnectionLost(boost::optional diff, Address) { //auto change = connection_manager_.LostNetworkConnection(peer); - //if (change) - // static_cast(this)->HandleChurn(*added); + if (diff) + static_cast(this)->HandleChurn(*diff); } // reply with our details; diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index e97a6e62..1d1a1abb 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -75,11 +75,11 @@ std::set
ConnectionManager::GetNonRoutingNodes() const { return connected_non_routing_nodes_; } -boost::optional ConnectionManager::LostNetworkConnection( - const Address& node) { - routing_table_.DropNode(node); - return GroupChanged(); -} +//boost::optional ConnectionManager::LostNetworkConnection( +// const Address& node) { +// routing_table_.DropNode(node); +// return GroupChanged(); +//} //optional ConnectionManager::DropNode(const Address& their_id) { // routing_table_.DropNode(their_id); @@ -105,7 +105,7 @@ void ConnectionManager::StartAccepting() { } if (!error) { - OnAccept(std::move(result)); + HandleAccept(std::move(result)); // The handler may have destroyed 'this'. if (!weak_connections.lock()) { @@ -119,7 +119,7 @@ void ConnectionManager::StartAccepting() { connections_->Accept(our_accept_port_, &our_accept_port_, std::move(accept_handler)); } -void ConnectionManager::OnAccept(Connections::AcceptResult result) { +void ConnectionManager::HandleAccept(Connections::AcceptResult result) { auto expected_i = expected_accepts_.find(result.his_endpoint); if (expected_i != expected_accepts_.end()) { @@ -207,8 +207,11 @@ void ConnectionManager::StartReceiving() { connections_->Receive([=](asio::error_code error, Connections::ReceiveResult result) { if (!weak_connections.lock()) return; + if (error) { + return HandleConnectionLost(result.his_address); + } auto h = std::move(on_receive_); - h(error, std::move(result.his_address), std::move(result.message)); + h(std::move(result.his_address), std::move(result.message)); if (!weak_connections.lock()) return; on_receive_ = std::move(h); StartReceiving(); @@ -221,6 +224,12 @@ void ConnectionManager::SendToNonRoutingNode(const Address& /*addr*/, // remove connection if failed } +void ConnectionManager::HandleConnectionLost(Address lost_connection) { + routing_table_.DropNode(lost_connection); + connected_non_routing_nodes_.erase(lost_connection); + on_connection_lost_(GroupChanged(), lost_connection); +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index cd378382..2b2ece8c 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -62,9 +62,9 @@ class ConnectionManager { using PublicPmid = passport::PublicPmid; public: - using OnReceive = std::function; + using OnReceive = std::function; using OnAddNode = std::function, Endpoint)>; - using OnConnectionLost = std::function; + using OnConnectionLost = std::function, Address)>; private: struct ExpectedAccept { @@ -135,11 +135,13 @@ class ConnectionManager { void StartReceiving(); void StartAccepting(); - void OnAccept(Connections::AcceptResult); + void HandleAccept(Connections::AcceptResult); + void HandleConnectionLost(Address); - private: boost::optional GroupChanged(); + private: + mutable std::mutex mutex_; unsigned short our_accept_port_; BoostAsioService boost_io_service_; @@ -148,7 +150,6 @@ class ConnectionManager { OnReceive on_receive_; OnConnectionLost on_connection_lost_; std::vector
current_close_group_; - std::function group_changed_functor_; std::map expected_accepts_; std::shared_ptr connections_; }; @@ -156,7 +157,18 @@ class ConnectionManager { template void ConnectionManager::Send(const Address& addr, const SerialisedMessage& message, Handler handler) { - connections_->Send(addr, message, std::move(handler)); + + std::weak_ptr guard = connections_; + + connections_->Send(addr, message, [=](asio::error_code error) { + handler(error); + + if (!guard.lock()) return; + + if (error) { + HandleConnectionLost(std::move(addr)); + } + }); } template diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 04d77e31..fe8e8465 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -96,6 +96,8 @@ class Connections { boost::asio::io_service& get_io_service(); + std::weak_ptr Guard() { return destroy_indicator_; } + private: void StartReceiving(const Address&, const crux::endpoint&, const std::shared_ptr&); @@ -111,10 +113,12 @@ class Connections { std::map id_to_endpoint_map_; AsyncQueue receive_queue_; + + std::shared_ptr destroy_indicator_; }; inline Connections::Connections(boost::asio::io_service& ios, const Address& our_node_id) - : service_(ios), our_id_(our_node_id) {} + : service_(ios), our_id_(our_node_id), destroy_indicator_(new boost::none_t) {} template AsyncResultReturn Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, @@ -360,7 +364,10 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& inline boost::asio::io_service& Connections::get_io_service() { return service_; } inline void Connections::Shutdown() { + auto guard = Guard(); + service_.post([=]() { + if (!guard.lock()) return; acceptors_.clear(); connections_.clear(); id_to_endpoint_map_.clear(); From eed5bbce38315bc2bfc4dd42b59c11e89e1d673a Mon Sep 17 00:00:00 2001 From: prakash Date: Thu, 12 Mar 2015 17:37:50 +0000 Subject: [PATCH 29/72] temp code. --- include/maidsafe/routing/routing_node.h | 82 +++++++++++-------- .../tests/routing_vault_network_test.cc | 20 ++--- 2 files changed, 60 insertions(+), 42 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index e3f56ccb..eaa429ec 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -88,6 +88,9 @@ class RoutingNode { } private: + // tries to bootstrap to network + void StartBootstrap(); + void HandleMessage(Connect connect, MessageHeader original_header); // like connect but add targets endpoint void HandleMessage(ConnectResponse connect_response); @@ -119,6 +122,7 @@ class RoutingNode { SourceAddress OurSourceAddress(GroupAddress) const; void OnBootstrap(asio::error_code, Contact, std::function); + void PutOurPublicPmid(); template void SendDirect(NodeId, Message, SendHandler); @@ -166,28 +170,49 @@ RoutingNode::RoutingNode() // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); + StartBootstrap(); +} - auto bootstrap_contacts = bootstrap_handler_.ReadBootstrapContacts(); +template +RoutingNode::~RoutingNode() { +} - for (const auto& contact : bootstrap_contacts) { - connection_manager_.Connect(contact.endpoint_pair.external, - [=](asio::error_code error, Address addr, Endpoint our_endpoint) { - if (error) { - return; - } - if (addr != contact.id) { - return; - } - // FIXME(Team): Thread safety. - bootstrap_node_ = contact.id; - bootstrap_endpoint_ = our_endpoint; - ConnectToCloseGroup(); - }); - } +template +void RoutingNode::StartBootstrap() { + auto handler = [=](asio::error_code error, Address peer_addr, Endpoint our_public_endpoint) { + if (error) { + // TODO(Team): try an connect to bootstrap contacts and other options + // (hardcoded endpoints) + // on failure keep retrying all options forever + return; + } + // FIXME(Team): Thread safety. + bootstrap_node_ = peer_addr; + // bootstrap_endpoint_ = our_endpoint; this will not required if + // connection manager has this connection + PutOurPublicPmid(); + ConnectToCloseGroup(); + }; + // try an connect to any local nodes (5483) Expect to be told Node_Id + Endpoint live_port_ep(GetLocalIp, kLivePort); + connection_manager_.Connect(live_port_ep, handler); + + // auto bootstrap_contacts = bootstrap_handler_.ReadBootstrapContacts(); } template -RoutingNode::~RoutingNode() { +void RoutingNode::PutOurPublicPmid() { + passport::PublicPmid our_public_pmid{ passport::PublicPmid(our_fob_) }; + auto to = our_public_pmid.name(); + asio::post(asio_service_.service(), [=] { + MessageHeader our_header(std::make_pair(Destination(to), boost::none), OurSourceAddress(), + ++message_id_, Authority::client); // As this node is not yet connected + // to its close group, client authority seems appropriate + // FIXME(Prakash) request should be signed + PutData request(passport::PublicPmid::Tag::kValue, our_public_pmid.Serialise()); + auto message(Serialise(our_header, MessageToTag::value(), request)); + connection_manager_.Send(*bootstrap_node_, message, [](asio::error_code) {}); + }); } template @@ -284,7 +309,7 @@ void RoutingNode::MessageReceived(asio::error_code /*error*/, InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; - Identity name; + //Identity name; try { Parse(binary_input_stream, header, tag); } catch (const std::exception&) { @@ -410,10 +435,10 @@ Authority RoutingNode::OurAuthority(const Address& element, } template -void RoutingNode::ConnectionLost(Address /*peer*/) { - //auto change = connection_manager_.LostNetworkConnection(peer); - //if (change) - // static_cast(this)->HandleChurn(*added); +void RoutingNode::ConnectionLost(Address peer) { + auto change = connection_manager_.LostNetworkConnection(peer); + if (change) + static_cast(this)->HandleChurn(*change); } // reply with our details; @@ -545,7 +570,9 @@ void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { } template -void RoutingNode::HandleMessage(PutData /*put_data*/, MessageHeader /* original_header */) {} +void RoutingNode::HandleMessage(PutData /*put_data*/, MessageHeader /* original_header */) { + +} template void RoutingNode::HandleMessage(PutDataResponse /*put_data_response*/, @@ -576,15 +603,6 @@ SourceAddress RoutingNode::OurSourceAddress(GroupAddress group) const { // rudp_.Send(target, Serialise(header, MessageToTag::value(), message), handler); // } // -// void RoutingNode::OnBootstrap(asio::error_code error, rudp::Contact contact, -// std::function handler) { -// if (error) { -// return handler(error, contact); -// } -// -// SendDirect(contact.id, FindGroup(OurId(), contact.id), -// [=](asio::error_code error) { handler(error, contact); }); -// } } // namespace routing diff --git a/src/maidsafe/routing/tests/routing_vault_network_test.cc b/src/maidsafe/routing/tests/routing_vault_network_test.cc index 02e16f1f..e2d5b85d 100644 --- a/src/maidsafe/routing/tests/routing_vault_network_test.cc +++ b/src/maidsafe/routing/tests/routing_vault_network_test.cc @@ -296,20 +296,20 @@ TEST(VaultNetworkTest, FUNC_CreateNetPutGetData) { // other async actions (same with the tests below). - LruCache cache(0, std::chrono::seconds(0)); +// LruCache cache(0, std::chrono::seconds(0)); - RoutingNode n; +// RoutingNode n; - auto value = NonEmptyString(RandomAlphaNumericString(65)); - Identity name{Identity(crypto::Hash(value))}; - MutableData a{MutableData::Name(name), value}; - ImmutableData b{value}; +// auto value = NonEmptyString(RandomAlphaNumericString(65)); +// Identity name{Identity(crypto::Hash(value))}; +// MutableData a{MutableData::Name(name), value}; +// ImmutableData b{value}; - Address from(Address(RandomString(Address::kSize))); - Address to(Address(RandomString(Address::kSize))); +// Address from(Address(RandomString(Address::kSize))); +// Address to(Address(RandomString(Address::kSize))); - n.Get(name, [](asio::error_code /* error */) {}); - n.Get(name, [](asio::error_code /* error */) {}); +// n.Get(name, [](asio::error_code /* error */) {}); +// n.Get(name, [](asio::error_code /* error */) {}); // n.Put(to, b, [](asio::error_code /* error */) {}); // n.Put(to, a, [](asio::error_code /* error */) {}); From 1c8b9568e9c027ddcbcdf8c16eaba0e5d246d287 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Thu, 12 Mar 2015 23:21:12 +0100 Subject: [PATCH 30/72] Connections class now owns its BoostIoService --- src/maidsafe/routing/connection_manager.cc | 3 +- src/maidsafe/routing/connection_manager.h | 3 - src/maidsafe/routing/connections.h | 39 +++++---- .../routing/tests/routing_connections_test.cc | 83 +++++++++---------- 4 files changed, 62 insertions(+), 66 deletions(-) diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 1d1a1abb..4455e408 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -47,13 +47,12 @@ ConnectionManager::ConnectionManager(Address our_id, OnReceive on_receive, OnConnectionLost on_connection_lost) : mutex_(), our_accept_port_(5483), - boost_io_service_(1), routing_table_(our_id), connected_non_routing_nodes_(), on_receive_(std::move(on_receive)), on_connection_lost_(std::move(on_connection_lost)), current_close_group_(), - connections_(new Connections(boost_io_service_.service(), our_id)) { + connections_(new Connections(our_id)) { StartReceiving(); StartAccepting(); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 2b2ece8c..2f4bf275 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -125,8 +125,6 @@ class ConnectionManager { unsigned short AcceptingPort() const { return our_accept_port_; } - boost::asio::io_service& get_io_service() { return boost_io_service_.service(); } - template void Connect(asio::ip::udp::endpoint, Handler); @@ -144,7 +142,6 @@ class ConnectionManager { mutable std::mutex mutex_; unsigned short our_accept_port_; - BoostAsioService boost_io_service_; RoutingTable routing_table_; std::set
connected_non_routing_nodes_; // clients & bootstrapping nodes OnReceive on_receive_; diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index fe8e8465..be5a52f6 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -60,7 +60,7 @@ class Connections { }; public: - Connections(boost::asio::io_service&, const Address& our_node_id); + Connections(const Address& our_node_id); Connections() = delete; Connections(const Connections&) = delete; @@ -98,11 +98,11 @@ class Connections { std::weak_ptr Guard() { return destroy_indicator_; } + void Wait(); + private: void StartReceiving(const Address&, const crux::endpoint&, const std::shared_ptr&); - boost::asio::io_service& service_; - Address our_id_; std::function on_receive_; @@ -114,11 +114,13 @@ class Connections { AsyncQueue receive_queue_; + BoostAsioService runner_; + std::shared_ptr destroy_indicator_; }; -inline Connections::Connections(boost::asio::io_service& ios, const Address& our_node_id) - : service_(ios), our_id_(our_node_id), destroy_indicator_(new boost::none_t) {} +inline Connections::Connections(const Address& our_node_id) + : our_id_(our_node_id), runner_(1), destroy_indicator_(new boost::none_t) {} template AsyncResultReturn Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, @@ -178,7 +180,11 @@ AsyncResultReturn Connections::Receive(Token& return result.get(); } -inline Connections::~Connections() { Shutdown(); } +inline Connections::~Connections() { + destroy_indicator_.reset(); + Shutdown(); + runner_.Stop(); +} template AsyncResultReturn Connections::Connect(Endpoint endpoint, @@ -190,7 +196,7 @@ AsyncResultReturn Connections::Connect(Endpoi get_io_service().post([=]() mutable { crux::endpoint unspecified_ep(boost::asio::ip::udp::v4(), 0); - auto socket = std::make_shared(service_, unspecified_ep); + auto socket = std::make_shared(get_io_service(), unspecified_ep); auto insert_result = connections_.insert(std::make_pair(convert::ToBoost(endpoint), socket)); @@ -261,10 +267,10 @@ Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& to std::shared_ptr acceptor; try { - acceptor = std::make_shared(service_, loopback(port)); + acceptor = std::make_shared(get_io_service(), loopback(port)); } catch(...) { - acceptor = std::make_shared(service_, loopback(0)); + acceptor = std::make_shared(get_io_service(), loopback(0)); } if (chosen_port) { @@ -280,7 +286,7 @@ Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& to std::weak_ptr weak_acceptor = acceptor; - auto socket = std::make_shared(service_); + auto socket = std::make_shared(get_io_service()); acceptor->async_accept(*socket, [=](boost::system::error_code error) mutable { if (!weak_acceptor.lock()) { @@ -361,21 +367,22 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& }); } -inline boost::asio::io_service& Connections::get_io_service() { return service_; } +inline boost::asio::io_service& Connections::get_io_service() { return runner_.service(); } inline void Connections::Shutdown() { - auto guard = Guard(); - - service_.post([=]() { - if (!guard.lock()) return; + get_io_service().post([=]() { acceptors_.clear(); connections_.clear(); id_to_endpoint_map_.clear(); }); } +inline void Connections::Wait() { + runner_.Stop(); +} + inline void Connections::Drop(const Address& their_id) { - service_.post([=]() { + get_io_service().post([=]() { // TODO: Migth it be that it is in connections_ but not in the id_to_endpoint_map_? // I.e. that above layers would wan't to remove by ID nodes which were not // yet connected? diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc index 144867f1..72281ffb 100644 --- a/src/maidsafe/routing/tests/routing_connections_test.cc +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -40,68 +40,64 @@ static std::string msg_to_str(const SerialisedMessage& msg) { } TEST(ConnectionsTest, FUNC_TwoConnections) { - boost::asio::io_service ios; + bool c1_finished = false; + bool c2_finished = false; - NodeId c1_id(NodeId(RandomString(NodeId::kSize))); - NodeId c2_id(NodeId(RandomString(NodeId::kSize))); + { + NodeId c1_id(NodeId(RandomString(NodeId::kSize))); + NodeId c2_id(NodeId(RandomString(NodeId::kSize))); - Connections c1(ios, c1_id); - Connections c2(ios, c2_id); + Connections c1(c1_id); + Connections c2(c2_id); - unsigned short port = 8080; + unsigned short port = 8080; - bool c1_finished = false; - bool c2_finished = false; + c1.Accept(port, nullptr, + [&](asio::error_code error, Connections::AcceptResult result) { + ASSERT_FALSE(error); + ASSERT_EQ(result.his_address, c2.OurId()); + ASSERT_EQ(result.our_endpoint.port(), port); + + c1.Send(result.his_address, + str_to_msg("hello"), + [&](asio::error_code error) { + ASSERT_FALSE(error); + c1.Shutdown(); + c1_finished = true; + }); + }); - c1.Accept(port, nullptr, - [&](asio::error_code error, Connections::AcceptResult result) { - ASSERT_FALSE(error); - ASSERT_EQ(result.his_address, c2.OurId()); - ASSERT_EQ(result.our_endpoint.port(), port); - - c1.Send(result.his_address, - str_to_msg("hello"), - [&](asio::error_code error) { - ASSERT_FALSE(error); - c1.Shutdown(); - c1_finished = true; - }); - }); - - c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), - [&](asio::error_code error, Connections::ConnectResult result) { - ASSERT_FALSE(error); - ASSERT_EQ(result.his_address, c1.OurId()); - - c2.Receive([&, result](asio::error_code error, Connections::ReceiveResult recv_result) { + c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), + [&](asio::error_code error, Connections::ConnectResult result) { ASSERT_FALSE(error); - ASSERT_EQ(recv_result.his_address, result.his_address); - ASSERT_EQ(msg_to_str(recv_result.message), "hello"); + ASSERT_EQ(result.his_address, c1.OurId()); + + c2.Receive([&, result](asio::error_code error, Connections::ReceiveResult recv_result) { + ASSERT_FALSE(error); + ASSERT_EQ(recv_result.his_address, result.his_address); + ASSERT_EQ(msg_to_str(recv_result.message), "hello"); - c2.Shutdown(); - c2_finished = true; + c2.Shutdown(); + c2_finished = true; + }); }); - }); - ios.run(); + c1.Wait(); + c2.Wait(); + } ASSERT_TRUE(c1_finished && c2_finished); } TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { - boost::asio::io_service ios; - boost::asio::io_service::work work(ios); - NodeId c1_id(NodeId(RandomString(NodeId::kSize))); NodeId c2_id(NodeId(RandomString(NodeId::kSize))); - Connections c1(ios, c1_id); - Connections c2(ios, c2_id); + Connections c1(c1_id); + Connections c2(c2_id); unsigned short port = 8080; - std::thread thread([&]() { ios.run(); }); - auto accept_f = c1.Accept(port, nullptr, asio::use_future); auto connect_f = c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), asio::use_future); @@ -121,9 +117,6 @@ TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { c1.Shutdown(); c2.Shutdown(); - - ios.stop(); - thread.join(); } } // namespace test From 38c73bcf0eabf4773fbbbd701d6ec3d111b36b89 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Thu, 12 Mar 2015 23:30:22 +0100 Subject: [PATCH 31/72] This should fix the RoutingNode::NextEndpointPair implementation --- include/maidsafe/routing/routing_node.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 28a550fd..25ec2580 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -126,9 +126,9 @@ class RoutingNode { if (!our_external_endpoint_) { return EndpointPair(); } - return EndpointPair(Endpoint(asio::ip::address_v4::loopback(), - our_external_endpoint_->port()), - *our_external_endpoint_); + auto port = connection_manager_.AcceptingPort(); + return EndpointPair(Endpoint(GetLocalIp(), port), + Endpoint(our_external_endpoint_->address(), port)); } // this innocuous looking call will bootstrap the node and also be used if we spot close group // nodes appering or vanishing so its pretty important. @@ -185,8 +185,7 @@ RoutingNode::RoutingNode() } // FIXME(Team): Thread safety. bootstrap_node_ = contact.id; - our_external_endpoint_ = Endpoint(our_endpoint.address(), - connection_manager_.AcceptingPort()); + our_external_endpoint_ = our_endpoint; ConnectToCloseGroup(); }); } From 3720268f1799d2ab046737947515023bb5d18163 Mon Sep 17 00:00:00 2001 From: prakash Date: Fri, 13 Mar 2015 17:55:16 +0000 Subject: [PATCH 32/72] debugging zero state --- include/maidsafe/routing/routing_node.h | 24 ++++--- src/maidsafe/routing/connection_manager.cc | 1 + .../tests/routing_fake_vault_facade_test.cc | 66 ++++++++++--------- .../routing/tests/utils/fake_vault_facade.cc | 3 + 4 files changed, 54 insertions(+), 40 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index ce21607a..c61227f4 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -154,7 +154,7 @@ class RoutingNode { template RoutingNode::RoutingNode() - : asio_service_(4), + : asio_service_(1), our_fob_(passport::CreatePmidAndSigner().first), message_id_(RandomUint32()), bootstrap_node_(boost::none), @@ -170,6 +170,7 @@ RoutingNode::RoutingNode() sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), destroy_indicator_(new boost::none_t) { + LOG(kInfo) << "RoutingNode -- " << OurId(); // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); @@ -182,7 +183,7 @@ RoutingNode::~RoutingNode() { template void RoutingNode::StartBootstrap() { - auto handler = [=](asio::error_code error, Address peer_addr, Endpoint our_public_endpoint) { + auto handler = [=](asio::error_code error, Address peer_addr, Endpoint /*our_public_endpoint*/) { if (error) { LOG(kWarning) << "Cannot connect to bootstrap endpoint < " << peer_addr << " >" << error.message(); @@ -191,6 +192,7 @@ void RoutingNode::StartBootstrap() { // on failure keep retrying all options forever return; } + LOG(kInfo) << "StartBootstrap succeded !! " << peer_addr; // FIXME(Team): Thread safety. bootstrap_node_ = peer_addr; // bootstrap_endpoint_ = our_endpoint; this will not required if @@ -199,8 +201,10 @@ void RoutingNode::StartBootstrap() { ConnectToCloseGroup(); }; // try connect to any local nodes (5483) Expect to be told Node_Id - Endpoint live_port_ep(GetLocalIp, kLivePort); - connection_manager_.Connect(live_port_ep, handler); + Endpoint live_port_ep(GetLocalIp(), kLivePort); + // skip trying to bootstrap off self + if (connection_manager_.AcceptingPort() != kLivePort) + connection_manager_.Connect(live_port_ep, handler); // auto bootstrap_contacts = bootstrap_handler_.ReadBootstrapContacts(); } @@ -208,17 +212,19 @@ void RoutingNode::StartBootstrap() { template void RoutingNode::PutOurPublicPmid() { passport::PublicPmid our_public_pmid{ passport::PublicPmid(our_fob_) }; - auto to = our_public_pmid.name(); + auto name = our_public_pmid.name(); asio::post(asio_service_.service(), [=] { // FIXME(Prakash) request should be signed - MessageHeader our_header(std::make_pair(Destination(to), boost::none), OurSourceAddress(), + MessageHeader our_header(std::make_pair(Destination(Address(name)), boost::none), OurSourceAddress(), ++message_id_, Authority::client); // As this node is not yet connected // to its close group, client authority seems appropriate - PutData request(passport::PublicPmid::Tag::kValue, our_public_pmid.Serialise()); + PutData request(passport::PublicPmid::Tag::kValue, Serialise(our_public_pmid)); auto message(Serialise(our_header, MessageToTag::value(), request)); connection_manager_.Send(*bootstrap_node_, message, [=](asio::error_code error) { if (error) LOG(kWarning) << "Failed to send to < " << *this->bootstrap_node_; + else + LOG(kVerbose) << "Send PutOurPublicPmid to < " << *this->bootstrap_node_; }); }); } @@ -311,8 +317,8 @@ void RoutingNode::ConnectToCloseGroup() { } template -void RoutingNode::MessageReceived(NodeId /* peer_id */, - SerialisedMessage serialised_message) { +void RoutingNode::MessageReceived(NodeId peer_id, SerialisedMessage serialised_message) { + LOG(kVerbose) << "MessageReceived from " << peer_id; InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 4455e408..c54a3c2b 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -116,6 +116,7 @@ void ConnectionManager::StartAccepting() { }; connections_->Accept(our_accept_port_, &our_accept_port_, std::move(accept_handler)); + LOG(kInfo) << "StartAccepting() port " << our_accept_port_; } void ConnectionManager::HandleAccept(Connections::AcceptResult result) { diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index a2c46b40..3d944121 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -26,39 +26,43 @@ namespace routing { namespace test { TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { - ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); + vault::test::FakeVaultFacade vault1; + Sleep(std::chrono::seconds(2)); + vault::test::FakeVaultFacade vault2; + //ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); + Sleep(std::chrono::seconds(100)); } -TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { - using endpoint = asio::ip::udp::endpoint; - using address = asio::ip::address_v4; - - std::vector> vaults(16); - unsigned short port(5483); - for (auto& vault : vaults) - vault.second = port++; - for (auto& vault : vaults) - ASSERT_NO_THROW(vault.first.StartAccepting(vault.second)); - - ASSERT_GE(vaults.size(), 2); - - for (size_t i = 0; i != vaults.size() - 1; ++i) - for (size_t j = i + 1; j != vaults.size(); ++j) - ASSERT_NO_THROW(vaults[j].first.AddContact(endpoint(address::loopback(), vaults[i].second))); - - auto vault_index(RandomUint32() % vaults.size()); - ImmutableData data(NonEmptyString(RandomAlphaNumericString(RandomUint32() % 1000))); - - vaults[vault_index].first.Put(NodeId(RandomString(NodeId::kSize)), data, - [](maidsafe_error error) { - ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); - }); - - vaults[vault_index].first.Get(data.name(), - [](maidsafe_error error) { - ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); - }); -} +//TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { +// using endpoint = asio::ip::udp::endpoint; +// using address = asio::ip::address_v4; +// vault::test::FakeVaultFacade facade1; +// std::vector> vaults(2); +// unsigned short port(5483); +// for (auto& vault : vaults) +// vault.second = port++; +// for (auto& vault : vaults) +// ASSERT_NO_THROW(vault.first.StartAccepting(vault.second)); + +// ASSERT_GE(vaults.size(), 2); + +// for (size_t i = 0; i != vaults.size() - 1; ++i) +// for (size_t j = i + 1; j != vaults.size(); ++j) +// ASSERT_NO_THROW(vaults[j].first.AddContact(endpoint(address::loopback(), vaults[i].second))); + +// auto vault_index(RandomUint32() % vaults.size()); +// ImmutableData data(NonEmptyString(RandomAlphaNumericString(RandomUint32() % 1000))); + +// vaults[vault_index].first.Put(NodeId(RandomString(NodeId::kSize)), data, +// [](maidsafe_error error) { +// ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); +// }); + +// vaults[vault_index].first.Get(data.name(), +// [](maidsafe_error error) { +// ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); +// }); +//} } // namespace test diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index 178044b9..980586f7 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -75,6 +75,9 @@ routing::HandleGetReturn FakeVaultFacade::HandleGet(routing::SourceAddress from, return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } +void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) { +} + } // namespace test } // namespace vault From 73b48a54a9e08deb9e4a2545897700503a0c89d9 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 16 Mar 2015 01:40:21 +0000 Subject: [PATCH 33/72] fixes for RelayedMessage. --- include/maidsafe/routing/routing_node.h | 38 ++++++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 52568328..39f89eb3 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -228,7 +228,7 @@ void RoutingNode::PutOurPublicPmid() { if (error) LOG(kWarning) << "Failed to send to < " << *this->bootstrap_node_; else - LOG(kVerbose) << "Send PutOurPublicPmid to < " << *this->bootstrap_node_; + LOG(kVerbose) << "Sent PutOurPublicPmid to : " << *this->bootstrap_node_; }); }); } @@ -307,6 +307,8 @@ void RoutingNode::ConnectToCloseGroup() { connection_manager_.Send(*bootstrap_node_, std::move(msg_data), [](asio::error_code error) { if (error) { LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); + } else { + LOG(kInfo) << "Sent Find group"; } }); return; @@ -321,6 +323,8 @@ void RoutingNode::ConnectToCloseGroup() { } } + + template void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { LOG(kVerbose) << "MessageReceived from " << peer_id; @@ -334,6 +338,9 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri LOG(kError) << "header failure." << boost::current_exception_diagnostic_information(); return; } + LOG(kVerbose) << "MessageReceived from " << peer_id << " PutData " << header.MessageId() + << "tag: " << static_cast::type>(tag); + if (filter_.Check(header.FilterValue())) return; // already seen @@ -374,24 +381,30 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri } }); } - std::set
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; if (header.RelayedMessage() && - std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), - [&header](const Address& node) { return node == Address(*header.ReplyToAddress()); })) { - // send message to connected node - connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); - return; + (Address(header.FromNode()) != OurId())) { // allow outgoing message + std::set
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; + if (std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), + [&header](const Address& node) { return node == Address(*header.ReplyToAddress()); })) { + // send message to connected node + connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); + return; + } } - if (!connection_manager_.AddressInCloseGroupRange(header.Destination().first)) + if (!connection_manager_.AddressInCloseGroupRange(header.Destination().first)) { + LOG(kVerbose) << "not for us"; return; // not for us + } // Drop message if it is a direct message type (Connect, ConnectResponse) and this node is in the // group but the message destination is another group member node. // Dropping this before Sentinel check if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { - if (Address(header.Destination().first) != connection_manager_.OurId()) // not for me + if (Address(header.Destination().first) != connection_manager_.OurId()) { // not for me + LOG(kVerbose) << "not for me"; return; + } } // FIXME(dirvine) Sentinel check here!! :19/01/2015 @@ -541,6 +554,7 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi for (const auto& node : connection_manager_.GetTarget(original_header.FromNode())) { connection_manager_.Send(node.id, message, [](asio::error_code) {}); } + // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? } template @@ -582,8 +596,10 @@ void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { } template -void RoutingNode::HandleMessage(PutData /*put_data*/, MessageHeader /* original_header */) { - +void RoutingNode::HandleMessage(PutData put_data, MessageHeader /* original_header */) { + // FIXME(Prakash) +// cache_.Add(put_data.name_and_type_id().name, *put_data.data()); + LOG(kVerbose) << "Put Data : " << put_data.type_id(); } template From 5c7b3b513dccafb930f84e29927c8825fe9ec1bb Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 16 Mar 2015 16:31:12 +0000 Subject: [PATCH 34/72] some debugging logs --- include/maidsafe/routing/routing_node.h | 29 ++++++++++++++----- src/maidsafe/routing/connection_manager.h | 2 +- src/maidsafe/routing/connections.h | 1 + .../routing/messages/find_group_response.h | 19 ++---------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 39f89eb3..4fa5e472 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -217,10 +217,9 @@ void RoutingNode::PutOurPublicPmid() { auto type_id = our_public_pmid.TypeId(); asio::post(asio_service_.service(), [=] { // FIXME(Prakash) request should be signed - MessageHeader our_header(std::make_pair(Destination(Address(name)), boost::none), OurSourceAddress(), - ++message_id_, Authority::client); // As this node is not yet connected - // to its close group, client authority seems appropriate -// PutData request(passport::PublicPmid::Tag::kValue, Serialise(our_public_pmid)); + MessageHeader our_header(std::make_pair(Destination(Address(name)), boost::none), + OurSourceAddress(), ++message_id_, Authority::client); + // As this node is not yet connected to its close group, client authority seems appropriate PutData request(type_id, Serialise(our_public_pmid)); auto message(Serialise(our_header, MessageToTag::value(), request)); @@ -327,7 +326,7 @@ void RoutingNode::ConnectToCloseGroup() { template void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { - LOG(kVerbose) << "MessageReceived from " << peer_id; + LOG(kInfo) << OurId() << " MessageReceived from " << peer_id << " <<< "<< hex::Substr(serialised_message) << ">>>"; InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; @@ -381,8 +380,7 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri } }); } - if (header.RelayedMessage() && - (Address(header.FromNode()) != OurId())) { // allow outgoing message + if (header.RelayedMessage() && (Address(header.FromNode()) != OurId())) { // skip outgoing msgs std::set
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; if (std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), [&header](const Address& node) { return node == Address(*header.ReplyToAddress()); })) { @@ -554,7 +552,22 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi for (const auto& node : connection_manager_.GetTarget(original_header.FromNode())) { connection_manager_.Send(node.id, message, [](asio::error_code) {}); } - // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? + + LOG(kInfo) << "FindGroupResponse msg <<< "<< hex::Substr(message) << ">>>"; + // if node in my group && in non routing list send it to non_routnig list as well + //if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle message part ! + + // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? temp code to get past zero state. Delete me !! + auto temp = Address(*original_header.ReplyToAddress()); + LOG(kWarning) << "FindGroupResp sent to " << temp << " but fails !!!!!!!!!!!!!!!!!!!!"; + connection_manager_.Send(temp, message, + [=](asio::error_code error) { + if (error) { + LOG(kWarning) << "Could not send to " << temp; + } else { + LOG(kInfo) << "Sent FindGroupResponse to " << temp; + } + }); } template diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 27605be9..2b871125 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -155,7 +155,7 @@ template void ConnectionManager::Send(const Address& addr, const SerialisedMessage& message, Handler handler) { std::weak_ptr guard = connections_; - + LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); connections_->Send(addr, message, [=](asio::error_code error) { handler(error); diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 609767a7..d1ed2560 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -132,6 +132,7 @@ AsyncResultReturn Connections::Send(const Address& remote_id, const Seria auto remote_endpoint_i = id_to_endpoint_map_.find(remote_id); if (remote_endpoint_i == id_to_endpoint_map_.end()) { + LOG(kWarning) << "bad_descriptor !! " << remote_id; return handler(asio::error::bad_descriptor); } diff --git a/src/maidsafe/routing/messages/find_group_response.h b/src/maidsafe/routing/messages/find_group_response.h index be35897f..a2745b50 100644 --- a/src/maidsafe/routing/messages/find_group_response.h +++ b/src/maidsafe/routing/messages/find_group_response.h @@ -52,23 +52,8 @@ class FindGroupResponse { FindGroupResponse& operator=(const FindGroupResponse&) = delete; template - Archive& load(Archive& archive) { - group_.clear(); - std::size_t group_size(0); - archive(target_id_, group_size); - for (std::size_t i = 0; i < group_size; ++i) { - group_.emplace_back(); - archive(group_.back()); - } - return archive; - } - - template - Archive& save(Archive& archive) const { - archive(target_id_, group_.size()); - for (const auto& public_pmid : group_) - archive(public_pmid); - return archive; + void serialize(Archive& archive) { + archive(target_id_, group_); } Address target_id() const { return target_id_; } From 167d5f918b9bf72a814df3bb1766575d318e03ec Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Mon, 16 Mar 2015 17:38:43 +0100 Subject: [PATCH 35/72] backup --- include/maidsafe/routing/routing_node.h | 5 -- src/maidsafe/routing/connection_manager.cc | 30 ++++++----- src/maidsafe/routing/connection_manager.h | 10 +++- src/maidsafe/routing/connections.h | 8 +++ ...uting_connection_manager_check_in_group.cc | 51 +++++++++++++++++++ 5 files changed, 85 insertions(+), 19 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 25ec2580..9196d527 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -63,7 +63,6 @@ class RoutingNode { RoutingNode(RoutingNode&&) = delete; RoutingNode& operator=(const RoutingNode&) = delete; RoutingNode& operator=(RoutingNode&&) = delete; - ~RoutingNode(); // normal bootstrap mechanism template @@ -191,10 +190,6 @@ RoutingNode::RoutingNode() } } -template -RoutingNode::~RoutingNode() { -} - template template GetReturn RoutingNode::Get(Identity name, CompletionToken token) { diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 4455e408..15df9579 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -93,17 +93,21 @@ void ConnectionManager::StartAccepting() { std::weak_ptr weak_connections = connections_; auto accept_handler = [=](asio::error_code error, Connections::AcceptResult result) { + std::cout << "onaccept " << __LINE__ << "\n"; auto connections = weak_connections.lock(); if (!connections) { return; } + std::cout << "onaccept " << __LINE__ << "\n"; if (error == asio::error::operation_aborted || error == asio::error::already_started) { return; } + std::cout << "onaccept " << __LINE__ << " " << error.message() << "\n"; if (!error) { + std::cout << "onaccept " << __LINE__ << "\n"; HandleAccept(std::move(result)); // The handler may have destroyed 'this'. @@ -112,6 +116,7 @@ void ConnectionManager::StartAccepting() { } } + std::cout << "onaccept " << __LINE__ << "\n"; return StartAccepting(); }; @@ -119,13 +124,9 @@ void ConnectionManager::StartAccepting() { } void ConnectionManager::HandleAccept(Connections::AcceptResult result) { - auto expected_i = expected_accepts_.find(result.his_endpoint); + auto expected_i = expected_accepts_.find(result.his_address); if (expected_i != expected_accepts_.end()) { - if (expected_i->second.node_info.id != result.his_address) { - return; - } - auto expected = std::move(expected_i->second); expected_accepts_.erase(expected_i); @@ -136,11 +137,10 @@ void ConnectionManager::HandleAccept(Connections::AcceptResult result) { } } -void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair his_endpoint_pair, +void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, OnAddNode on_node_added) { // TODO(PeterJ): Use internal endpoint as well. - expected_accepts_.insert(std::make_pair(his_endpoint_pair.external, - ExpectedAccept{node_info, on_node_added})); + expected_accepts_.insert(std::make_pair(node_info.id, ExpectedAccept{node_info, on_node_added})); //StartAccepting(connections_, node_to_add, their_endpoint_pair, [=](Endpoint our_endpoint) { // on_node_added(AddToRoutingTable(node_to_add), our_endpoint); //}); @@ -154,6 +154,7 @@ void ConnectionManager::AddNode( // TODO(PeterJ): Use local endpoint as well connections_->Connect(their_endpoint_pair.external, [=](asio::error_code error, Connections::ConnectResult result) { + std::cout << "onconnect\n"; if (!weak_connections.lock()) { return; } @@ -210,9 +211,11 @@ void ConnectionManager::StartReceiving() { return HandleConnectionLost(result.his_address); } auto h = std::move(on_receive_); - h(std::move(result.his_address), std::move(result.message)); - if (!weak_connections.lock()) return; - on_receive_ = std::move(h); + if (h) { + h(std::move(result.his_address), std::move(result.message)); + if (!weak_connections.lock()) return; + on_receive_ = std::move(h); + } StartReceiving(); }); } @@ -226,7 +229,10 @@ void ConnectionManager::SendToNonRoutingNode(const Address& /*addr*/, void ConnectionManager::HandleConnectionLost(Address lost_connection) { routing_table_.DropNode(lost_connection); connected_non_routing_nodes_.erase(lost_connection); - on_connection_lost_(GroupChanged(), lost_connection); + auto h = std::move(on_connection_lost_); + if (h) { + h(GroupChanged(), lost_connection); + } } } // namespace routing diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 2f4bf275..86936b3e 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -77,7 +77,13 @@ class ConnectionManager { ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; - ~ConnectionManager() = default; +//~ConnectionManager() = default; + ~ConnectionManager() { + std::cerr << this << " ~ConnectionManager begin\n"; + connections_.reset(); + std::cerr << this << " ~ConnectionManager end\n"; + } + ConnectionManager& operator=(const ConnectionManager&) = delete; ConnectionManager& operator=(ConnectionManager&&) = delete; @@ -147,7 +153,7 @@ class ConnectionManager { OnReceive on_receive_; OnConnectionLost on_connection_lost_; std::vector
current_close_group_; - std::map expected_accepts_; + std::map expected_accepts_; std::shared_ptr connections_; }; diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index be5a52f6..c32b7c3d 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -181,9 +181,13 @@ AsyncResultReturn Connections::Receive(Token& } inline Connections::~Connections() { + std::cerr << this << " ~Connections 1\n"; destroy_indicator_.reset(); + std::cerr << this << " ~Connections 2\n"; Shutdown(); + std::cerr << this << " ~Connections 3\n"; runner_.Stop(); + std::cerr << this << " ~Connections 4\n"; } template @@ -371,9 +375,13 @@ inline boost::asio::io_service& Connections::get_io_service() { return runner_.s inline void Connections::Shutdown() { get_io_service().post([=]() { + std::cerr << this << " Shutdown 1\n"; acceptors_.clear(); + std::cerr << this << " Shutdown 2\n"; connections_.clear(); + std::cerr << this << " Shutdown 3\n"; id_to_endpoint_map_.clear(); + std::cerr << this << " Shutdown 4\n"; }); } diff --git a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc index 9a0f0675..408ad233 100644 --- a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc +++ b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc @@ -36,6 +36,57 @@ namespace routing { namespace test { +using Endpoint = asio::ip::udp::endpoint; + +struct FutureHandler { + using Value = boost::optional; + + struct State { + std::promise promise; + std::future future; + + State() : future(promise.get_future()) {} + }; + + std::string what; + std::shared_ptr state; + + FutureHandler(std::string what) : what(std::move(what)), state(std::make_shared()) {} + + void operator()(Value v, Endpoint) const { + state->promise.set_value(std::move(v)); + } + + Value Get() { return state->future.get(); } +}; + +NodeInfo GenerateNodeInfo() { + passport::PublicPmid fob{passport::Pmid(passport::Anpmid())}; + NodeInfo node_info(NodeId(RandomString(NodeId::kSize)), fob, false); + return std::move(node_info); +} + +EndpointPair LocalEndpointPair(unsigned short port) { + return EndpointPair(Endpoint(GetLocalIp(), port)); +} + +TEST(ConnectionManagerTest, FUNC_AddNodes) { + NodeInfo c1_info = GenerateNodeInfo(); + NodeInfo c2_info = GenerateNodeInfo(); + + ConnectionManager cm1(c1_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); + ConnectionManager cm2(c2_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); + + FutureHandler cm1_result("cm1"); + FutureHandler cm2_result("cm2"); + + cm1.AddNode(c2_info, LocalEndpointPair(cm2.AcceptingPort()), cm1_result); + cm2.AddNodeAccept(c1_info, LocalEndpointPair(cm1.AcceptingPort()), cm2_result); + + cm1_result.Get(); + cm2_result.Get(); +} + TEST(ConnectionManagerTest, FUNC_AddNodesCheckCloseGroup) { // boost::asio::io_service io_service; // passport::PublicPmid our_public_pmid(passport::CreatePmidAndSigner().first); From fde688ae1bc4bc25f99c222c045c3abb90217d21 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 16 Mar 2015 17:19:36 +0000 Subject: [PATCH 36/72] minor cleanup (doesn't compile) --- include/maidsafe/routing/routing_node.h | 29 +++++++------------ .../routing/tests/utils/fake_vault_facade.cc | 24 +++++++-------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 4fa5e472..4db07ba9 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -171,7 +171,7 @@ RoutingNode::RoutingNode() sentinel_(asio_service_.service()), cache_(std::chrono::minutes(60)), destroy_indicator_(new boost::none_t) { - LOG(kInfo) << "RoutingNode -- " << OurId(); + LOG(kInfo) << "RoutingNode < " << OurId() << " >"; // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); @@ -188,12 +188,11 @@ void RoutingNode::StartBootstrap() { if (error) { LOG(kWarning) << "Cannot connect to bootstrap endpoint < " << peer_addr << " >" << error.message(); - // TODO(Team): try an connect to bootstrap contacts and other options - // (hardcoded endpoints) - // on failure keep retrying all options forever + // TODO(Team): try connect to bootstrap contacts and other options + // (hardcoded endpoints).on failure keep retrying all options forever return; } - LOG(kInfo) << "StartBootstrap succeded !! " << peer_addr; + LOG(kInfo) << "Bootstrapped with " << peer_addr; // FIXME(Team): Thread safety. bootstrap_node_ = peer_addr; // bootstrap_endpoint_ = our_endpoint; this will not required if @@ -212,6 +211,7 @@ void RoutingNode::StartBootstrap() { template void RoutingNode::PutOurPublicPmid() { + assert(bootstrap_node_); passport::PublicPmid our_public_pmid{ passport::PublicPmid(our_fob_) }; auto name = our_public_pmid.Name(); auto type_id = our_public_pmid.TypeId(); @@ -395,9 +395,8 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri return; // not for us } - // Drop message if it is a direct message type (Connect, ConnectResponse) and this node is in the - // group but the message destination is another group member node. - // Dropping this before Sentinel check + // Drop message before Sentinel check if it is a direct message type (Connect, ConnectResponse) + // and this node is in the group but the message destination is another group member node. if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { if (Address(header.Destination().first) != connection_manager_.OurId()) { // not for me LOG(kVerbose) << "not for me"; @@ -613,6 +612,10 @@ void RoutingNode::HandleMessage(PutData put_data, MessageHeader /* origin // FIXME(Prakash) // cache_.Add(put_data.name_and_type_id().name, *put_data.data()); LOG(kVerbose) << "Put Data : " << put_data.type_id(); + auto result = static_cast(this)->HandlePut( + header.Source(), header.FromAuthority(), + OurAuthority(put_data.name_and_type_id().name, header), + put_data.name_and_type_id(), put_data.data()); } template @@ -636,16 +639,6 @@ SourceAddress RoutingNode::OurSourceAddress(GroupAddress group) const { return SourceAddress(NodeAddress(OurId()), group, boost::none); } -// template -// void RoutingNode::SendDirect(Address target, Message message, SendHandler handler) { -// MessageHeader header(DestinationAddress(std::make_pair(Destination(target), boost::none)), -// SourceAddress{OurSourceAddress()}, ++message_id_); -// -// rudp_.Send(target, Serialise(header, MessageToTag::value(), message), handler); -// } -// - - } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index 909c048d..3075d92f 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -41,7 +41,7 @@ namespace test { routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress /*from*/, routing::Authority /*from_authority*/, routing::Authority /*authority*/, Data::NameAndTypeId /*name_and_type_id*/, SerialisedData /*serialised_data*/) { -// switch (authority) { + switch (authority) { // case routing::Authority::client_manager: // if (from_authority != routing::Authority::client) // break; @@ -51,17 +51,17 @@ routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress / // return MaidManager::HandlePut(from, Parse(serialised_data)); // else if (name_and_type_id.type_id == detail::TypeId::value) // return MaidManager::HandlePut(from, Parse(serialised_data)); -// case routing::Authority::nae_manager: -// if (from_authority != routing::Authority::client_manager) -// break; -// if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::HandlePut(from, Parse(serialised_data)); -// break; -// default: -// break; -// } + case routing::Authority::nae_manager: + if (from_authority != routing::Authority::client_manager) + break; + if (name_and_type_id.type_id == detail::TypeId::value) + return DataManager::HandlePut(from, Parse(serialised_data)); + else if (name_and_type_id.type_id == detail::TypeId::value) + return DataManager::HandlePut(from, Parse(serialised_data)); + break; + default: + break; + } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } From 33e5153c4b3a9f6ae0ca48e13359e70a6673527e Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 17 Mar 2015 13:01:16 +0100 Subject: [PATCH 37/72] Removes some debug output --- src/maidsafe/routing/connections.h | 10 ---------- .../routing/tests/routing_fake_vault_facade_test.cc | 1 - 2 files changed, 11 deletions(-) diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 510ae66c..d13c816e 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -186,13 +186,9 @@ AsyncResultReturn Connections::Receive(Token& } inline Connections::~Connections() { - std::cerr << this << " ~Connections 1\n"; destroy_indicator_.reset(); - std::cerr << this << " ~Connections 2\n"; Shutdown(); - std::cerr << this << " ~Connections 3\n"; runner_.Stop(); - std::cerr << this << " ~Connections 4\n"; } template @@ -357,7 +353,6 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& auto socket = weak_socket.lock(); if (!socket) { - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1\n"; return receive_queue_.Push(asio::error::operation_aborted, ReceiveResult{id, std::move(*buffer)}); } @@ -368,7 +363,6 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& } buffer->resize(size); - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2 " << &error << " " << error.message() << "\n"; receive_queue_.Push(convert::ToStd(error), ReceiveResult{id, std::move(*buffer)}); if (error) @@ -382,13 +376,9 @@ inline boost::asio::io_service& Connections::get_io_service() { return runner_.s inline void Connections::Shutdown() { get_io_service().post([=]() { - std::cerr << this << " Shutdown 1\n"; acceptors_.clear(); - std::cerr << this << " Shutdown 2\n"; connections_.clear(); - std::cerr << this << " Shutdown 3\n"; id_to_endpoint_map_.clear(); - std::cerr << this << " Shutdown 4\n"; }); } diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index c9ee27ff..c596ec06 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -31,7 +31,6 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { vault::test::FakeVaultFacade vault2; //ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); Sleep(std::chrono::seconds(20)); - std::cerr << "DUN!\n"; } //TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { From ab652d3bbc4b5ef86e8015e3df2e049dd778a408 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 17 Mar 2015 14:42:43 +0100 Subject: [PATCH 38/72] Restores the previous ApplyTuple function The new one had problems with clang and did not really solve the problem I'm trying to solve. --- src/maidsafe/routing/async_queue.h | 42 ++++++++-------------- src/maidsafe/routing/connection_manager.cc | 10 ------ src/maidsafe/routing/connection_manager.h | 6 ---- 3 files changed, 14 insertions(+), 44 deletions(-) diff --git a/src/maidsafe/routing/async_queue.h b/src/maidsafe/routing/async_queue.h index 7574fda2..9ea03df0 100644 --- a/src/maidsafe/routing/async_queue.h +++ b/src/maidsafe/routing/async_queue.h @@ -38,41 +38,27 @@ namespace helper { // For more info in ApplyTuple see: https://www.preney.ca/paul/archives/486 template -struct Index { - using Next = Index; -}; - -//template -//struct GeneratedSequence : GeneratedSequence {}; -// -//template -//struct GeneratedSequence<0, Is...> : Index {}; +struct Index {}; -template struct BuildIndices { - using Type = typename BuildIndices::Type::Next; -}; +template +struct GeneratedSequence : GeneratedSequence {}; -template<> struct BuildIndices<0> { - using Type = Index<>; -}; +template +struct GeneratedSequence<0, Is...> : Index {}; } // namespace helper -template -inline MAIDSAFE_CONSTEXPR void ApplyTuple(F&& f, Tuple&& tup, helper::Index) -{ //-> decltype(f(std::get(tup)...)) { - f(std::get(std::forward(tup))...); +template +inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup, + helper::Index) + -> decltype(f(std::get(tup)...)) { + return f(std::get(tup)...); } -template -inline MAIDSAFE_CONSTEXPR void ApplyTuple(F&& f, Tuple&& tup) -// -> decltype(ApplyTuple(f, -// tup, -// helper::GeneratedSequence::value>{})) { - { - ApplyTuple(std::forward(f), - std::forward(tup), - typename helper::BuildIndices::type>::value>::Type{}); +template +inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup) + -> decltype(ApplyTuple(f, tup, helper::GeneratedSequence{})) { + return ApplyTuple(std::forward(f), tup, helper::GeneratedSequence{}); } } // namespace detail diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index d5e05fdc..882c6294 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -93,21 +93,17 @@ void ConnectionManager::StartAccepting() { std::weak_ptr weak_connections = connections_; auto accept_handler = [=](asio::error_code error, Connections::AcceptResult result) { - std::cout << "onaccept " << __LINE__ << "\n"; auto connections = weak_connections.lock(); if (!connections) { return; } - std::cout << "onaccept " << __LINE__ << "\n"; if (error == asio::error::operation_aborted || error == asio::error::already_started) { return; } - std::cout << "onaccept " << __LINE__ << " " << error.message() << "\n"; if (!error) { - std::cout << "onaccept " << __LINE__ << "\n"; HandleAccept(std::move(result)); // The handler may have destroyed 'this'. @@ -116,7 +112,6 @@ void ConnectionManager::StartAccepting() { } } - std::cout << "onaccept " << __LINE__ << "\n"; return StartAccepting(); }; @@ -155,7 +150,6 @@ void ConnectionManager::AddNode( // TODO(PeterJ): Use local endpoint as well connections_->Connect(their_endpoint_pair.external, [=](asio::error_code error, Connections::ConnectResult result) { - std::cout << "onconnect\n"; if (!weak_connections.lock()) { return; } @@ -206,14 +200,10 @@ void ConnectionManager::StartReceiving() { std::weak_ptr weak_connections = connections_; connections_->Receive([=](asio::error_code error, Connections::ReceiveResult result) { - std::cout << this << " 0 ConnectionManager::Received " << &error << "\n"; - std::cout << this << " 1 ConnectionManager::Received " << error.message() << "\n"; - std::cout << this << " 2 ConnectionManager::Received \n"; if (!weak_connections.lock()) return; if (error) { return HandleConnectionLost(result.his_address); } - std::cout << this << " 3 ConnectionManager::Received " << hex::Substr(result.message) << "\n"; auto h = std::move(on_receive_); if (h) { h(std::move(result.his_address), std::move(result.message)); diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 459d7449..56d600cf 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -77,12 +77,6 @@ class ConnectionManager { ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; -//~ConnectionManager() = default; - ~ConnectionManager() { - std::cerr << this << " ~ConnectionManager begin\n"; - connections_.reset(); - std::cerr << this << " ~ConnectionManager end\n"; - } ConnectionManager& operator=(const ConnectionManager&) = delete; ConnectionManager& operator=(ConnectionManager&&) = delete; From c2be91c100e0f1a13635db8c921ad001e55d27ff Mon Sep 17 00:00:00 2001 From: prakash Date: Tue, 17 Mar 2015 15:52:10 +0000 Subject: [PATCH 39/72] Changed signature of Put() method. Also sending it to client manager first. Still need to update the signature of HandlePut(). (wip) --- include/maidsafe/routing/routing_node.h | 31 +++++++++---------- .../routing/tests/utils/fake_vault_facade.cc | 24 +++++++------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 4db07ba9..ea88b12c 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -78,7 +78,7 @@ class RoutingNode { GetReturn Get(Data::NameAndTypeId name_and_type_id, CompletionToken token); // will return with allowed or not (error_code only) template - PutReturn Put(Address to, DataType data, CompletionToken token); + PutReturn Put(DataType data, CompletionToken token); // will return with allowed or not (error_code only) template PostReturn Post(Address to, FunctorType functor, CompletionToken token); @@ -216,7 +216,7 @@ void RoutingNode::PutOurPublicPmid() { auto name = our_public_pmid.Name(); auto type_id = our_public_pmid.TypeId(); asio::post(asio_service_.service(), [=] { - // FIXME(Prakash) request should be signed + // FIXME(Prakash) request should be signed and may be sent to ClientManager MessageHeader our_header(std::make_pair(Destination(Address(name)), boost::none), OurSourceAddress(), ++message_id_, Authority::client); // As this node is not yet connected to its close group, client authority seems appropriate @@ -256,18 +256,17 @@ GetReturn RoutingNode::Get(Data::NameAndTypeId name_and_ // nodes have no reason to Put anywhere else template template -PutReturn RoutingNode::Put(Address to, DataType data, - CompletionToken token) { +PutReturn RoutingNode::Put(DataType data, CompletionToken token) { PutHandler handler(std::forward(token)); asio::async_result result(handler); asio::post(asio_service_.service(), [=] { - MessageHeader our_header(std::make_pair(Destination(to), boost::none), OurSourceAddress(), - ++message_id_, Authority::client); + MessageHeader our_header(std::make_pair(Destination(OurId()), boost::none), // send to ClientMgr + OurSourceAddress(), ++message_id_, Authority::client); PutData request(DataType::Tag::kValue, data.serialise()); // FIXME(dirvine) For client in real put this needs signed :08/02/2015 // fixme data should serialise properly and not require the above call to serialse() auto message(Serialise(our_header, MessageToTag::value(), request)); - for (const auto& target : connection_manager_.GetTarget(to)) { + for (const auto& target : connection_manager_.GetTarget(OurId())) { connection_manager_.Send(target.id, message, [](asio::error_code) {}); } }); @@ -380,10 +379,10 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri } }); } - if (header.RelayedMessage() && (Address(header.FromNode()) != OurId())) { // skip outgoing msgs + if (header.RelayedMessage() && (header.FromNode().data != OurId())) { // skip outgoing msgs std::set
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; if (std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), - [&header](const Address& node) { return node == Address(*header.ReplyToAddress()); })) { + [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; })) { // send message to connected node connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); return; @@ -398,7 +397,7 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri // Drop message before Sentinel check if it is a direct message type (Connect, ConnectResponse) // and this node is in the group but the message destination is another group member node. if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { - if (Address(header.Destination().first) != connection_manager_.OurId()) { // not for me + if (header.Destination().first.data != connection_manager_.OurId()) { // not for me LOG(kVerbose) << "not for me"; return; } @@ -557,7 +556,7 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi //if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle message part ! // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? temp code to get past zero state. Delete me !! - auto temp = Address(*original_header.ReplyToAddress()); + auto temp = (*original_header.ReplyToAddress()).data; LOG(kWarning) << "FindGroupResp sent to " << temp << " but fails !!!!!!!!!!!!!!!!!!!!"; connection_manager_.Send(temp, message, [=](asio::error_code error) { @@ -608,14 +607,14 @@ void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { } template -void RoutingNode::HandleMessage(PutData put_data, MessageHeader /* original_header */) { +void RoutingNode::HandleMessage(PutData put_data, MessageHeader /*original_header*/) { // FIXME(Prakash) // cache_.Add(put_data.name_and_type_id().name, *put_data.data()); LOG(kVerbose) << "Put Data : " << put_data.type_id(); - auto result = static_cast(this)->HandlePut( - header.Source(), header.FromAuthority(), - OurAuthority(put_data.name_and_type_id().name, header), - put_data.name_and_type_id(), put_data.data()); +// auto result = static_cast(this)->HandlePut( +// original_header.Source(), original_header.FromAuthority(), +// OurAuthority(put_data.name_and_type_id().name, original_header), +// put_data.name_and_type_id(), put_data.data()); } template diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index 3075d92f..909c048d 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -41,7 +41,7 @@ namespace test { routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress /*from*/, routing::Authority /*from_authority*/, routing::Authority /*authority*/, Data::NameAndTypeId /*name_and_type_id*/, SerialisedData /*serialised_data*/) { - switch (authority) { +// switch (authority) { // case routing::Authority::client_manager: // if (from_authority != routing::Authority::client) // break; @@ -51,17 +51,17 @@ routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress / // return MaidManager::HandlePut(from, Parse(serialised_data)); // else if (name_and_type_id.type_id == detail::TypeId::value) // return MaidManager::HandlePut(from, Parse(serialised_data)); - case routing::Authority::nae_manager: - if (from_authority != routing::Authority::client_manager) - break; - if (name_and_type_id.type_id == detail::TypeId::value) - return DataManager::HandlePut(from, Parse(serialised_data)); - else if (name_and_type_id.type_id == detail::TypeId::value) - return DataManager::HandlePut(from, Parse(serialised_data)); - break; - default: - break; - } +// case routing::Authority::nae_manager: +// if (from_authority != routing::Authority::client_manager) +// break; +// if (name_and_type_id.type_id == detail::TypeId::value) +// return DataManager::HandlePut(from, Parse(serialised_data)); +// else if (name_and_type_id.type_id == detail::TypeId::value) +// return DataManager::HandlePut(from, Parse(serialised_data)); +// break; +// default: +// break; +// } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } From 67256801071e97221fe0d5b776c5610786dbd448 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 17 Mar 2015 16:53:49 +0100 Subject: [PATCH 40/72] Ditch the AsyncQueue The code might be cleaner this way. --- src/maidsafe/routing/connections.h | 45 ++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index d13c816e..d098648f 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -101,6 +101,7 @@ class Connections { private: void StartReceiving(const Address&, const crux::endpoint&, const std::shared_ptr&); + void OnReceive(asio::error_code, ReceiveResult); template void post(const Handler& handler, Args&&... args); @@ -118,7 +119,16 @@ class Connections { std::map> connections_; std::map id_to_endpoint_map_; - AsyncQueue receive_queue_; + + struct ReceiveInput { + asio::error_code error; + ReceiveResult result; + }; + + using ReceiveOutput = std::function; + + std::queue receive_input_; + std::queue receive_output_; BoostAsioService runner_; @@ -174,17 +184,31 @@ AsyncResultReturn Connections::Receive(Token& Handler handler(std::forward(token)); asio::async_result result(handler); - // TODO(PeterJ): For some reason I need to wrap the handler, otherwise I get crashes - // in the future tests. - auto handler2 = [=](asio::error_code error, ReceiveResult result) mutable { - post2(handler, error, result); - }; - - get_io_service().post([=]() mutable { receive_queue_.AsyncPop(handler2); }); + get_io_service().post([=]() mutable { + if (!receive_input_.empty()) { + auto input = std::move(receive_input_.front()); + receive_input_.pop(); + post(handler, input.error, std::move(input.result)); + } + else { + receive_output_.push(std::move(handler)); + } + }); return result.get(); } +inline void Connections::OnReceive(asio::error_code error, ReceiveResult result) { + if (!receive_output_.empty()) { + auto handler = std::move(receive_output_.front()); + receive_output_.pop(); + post(handler, error, std::move(result)); + } + else { + receive_input_.push(ReceiveInput{error, std::move(result)}); + } +} + inline Connections::~Connections() { destroy_indicator_.reset(); Shutdown(); @@ -353,8 +377,7 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& auto socket = weak_socket.lock(); if (!socket) { - return receive_queue_.Push(asio::error::operation_aborted, - ReceiveResult{id, std::move(*buffer)}); + return OnReceive(asio::error::operation_aborted, ReceiveResult{id, std::move(*buffer)}); } if (error) { @@ -363,7 +386,7 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& } buffer->resize(size); - receive_queue_.Push(convert::ToStd(error), ReceiveResult{id, std::move(*buffer)}); + OnReceive(convert::ToStd(error), ReceiveResult{id, std::move(*buffer)}); if (error) return; From 78b8f95981d56217a9feab91229224da4f23267e Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 17 Mar 2015 22:34:27 +0100 Subject: [PATCH 41/72] Fixes (private) Connections::post function Was causing crashes. --- src/maidsafe/routing/apply_tuple.h | 60 +++++++++++++++++++++++ src/maidsafe/routing/async_queue.h | 33 +------------ src/maidsafe/routing/connection_manager.h | 2 + src/maidsafe/routing/connections.h | 24 ++------- 4 files changed, 68 insertions(+), 51 deletions(-) create mode 100644 src/maidsafe/routing/apply_tuple.h diff --git a/src/maidsafe/routing/apply_tuple.h b/src/maidsafe/routing/apply_tuple.h new file mode 100644 index 00000000..89419c92 --- /dev/null +++ b/src/maidsafe/routing/apply_tuple.h @@ -0,0 +1,60 @@ +/* Copyright 2015 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#ifndef MAIDSAFE_ROUTING_APPLY_TUPLE_H_ +#define MAIDSAFE_ROUTING_APPLY_TUPLE_H_ + +#include + +namespace maidsafe { + +namespace routing { + +namespace helper { + +template +struct Index {}; + +template +struct GeneratedSequence : GeneratedSequence {}; + +template +struct GeneratedSequence<0, Is...> : Index {}; + +template +inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup, + helper::Index) + -> decltype(f(std::get(tup)...)) { + return f(std::get(tup)...); +} + +} // namespace helper + +template +inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup) + -> decltype(helper::ApplyTuple(std::forward(f), tup, helper::GeneratedSequence{})) { + return helper::ApplyTuple(std::forward(f), + tup, + helper::GeneratedSequence{}); +} + +} // namespace routing + +} // namespace maidsafe + +#endif // MAIDSAFE_ROUTING_APPLY_TUPLE_H_ diff --git a/src/maidsafe/routing/async_queue.h b/src/maidsafe/routing/async_queue.h index 9ea03df0..5b7b8b5b 100644 --- a/src/maidsafe/routing/async_queue.h +++ b/src/maidsafe/routing/async_queue.h @@ -26,43 +26,12 @@ #include "asio/async_result.hpp" #include "maidsafe/common/config.h" +#include "maidsafe/routing/apply_tuple.h" namespace maidsafe { namespace routing { -namespace detail { - -namespace helper { - -// For more info in ApplyTuple see: https://www.preney.ca/paul/archives/486 - -template -struct Index {}; - -template -struct GeneratedSequence : GeneratedSequence {}; - -template -struct GeneratedSequence<0, Is...> : Index {}; - -} // namespace helper - -template -inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup, - helper::Index) - -> decltype(f(std::get(tup)...)) { - return f(std::get(tup)...); -} - -template -inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup) - -> decltype(ApplyTuple(f, tup, helper::GeneratedSequence{})) { - return ApplyTuple(std::forward(f), tup, helper::GeneratedSequence{}); -} - -} // namespace detail - template class AsyncQueue { private: diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 56d600cf..572f310e 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -128,6 +128,8 @@ class ConnectionManager { template void Connect(asio::ip::udp::endpoint, Handler); + void Shutdown() { connections_.reset(); } + private: boost::optional AddToRoutingTable(NodeInfo node_to_add); void StartReceiving(); diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index d098648f..ffd3c1e7 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -32,7 +32,7 @@ #include "maidsafe/crux/acceptor.hpp" #include "maidsafe/crux/socket.hpp" -#include "maidsafe/routing/async_queue.h" +#include "maidsafe/routing/apply_tuple.h" #include "maidsafe/routing/async_exchange.h" #include "maidsafe/routing/types.h" #include "maidsafe/routing/utils.h" @@ -104,9 +104,7 @@ class Connections { void OnReceive(asio::error_code, ReceiveResult); template - void post(const Handler& handler, Args&&... args); - template void post2(const Handler& handler, const Arg1&); - template void post2(const Handler& handler, const Arg1&, const Arg2&); + void post(Handler&& handler, Args&&... args); private: asio::io_service& service; @@ -410,22 +408,10 @@ inline void Connections::Wait() { } template -void Connections::post(const Handler& handler, Args&&... args) { - std::tuple tuple(std::forward(args)...); +void Connections::post(Handler&& handler, Args&&... args) { + std::tuple::type...> tuple(std::forward(args)...); service.post([handler, tuple]() mutable { - detail::ApplyTuple(handler, tuple); - }); -} - -template void Connections::post2(const Handler& handler, const Arg1& arg) { - service.post([handler, arg]() { - handler(arg); - }); -} - -template void Connections::post2(const Handler& handler, const Arg1& arg1, const Arg2& arg2) { - service.post([=]() { - handler(arg1, arg2); + ApplyTuple(handler, tuple); }); } From d17eaffa188c20bfdbae16eb8780c33cee111020 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 17 Mar 2015 23:23:52 +0100 Subject: [PATCH 42/72] Adds non-boost::asio::work to the Connections class Also the class now acts as any other non-boost::asio object. --- src/maidsafe/routing/connections.h | 10 ++- .../routing/tests/routing_connections_test.cc | 78 ++++++++++--------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index ffd3c1e7..bda2096b 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -108,6 +108,8 @@ class Connections { private: asio::io_service& service; + std::unique_ptr work_; + Address our_id_; std::function on_receive_; @@ -134,7 +136,12 @@ class Connections { }; inline Connections::Connections(asio::io_service& ios, const Address& our_node_id) - : service(ios), our_id_(our_node_id), runner_(1), destroy_indicator_(new boost::none_t) {} + : service(ios), + work_(new asio::io_service::work(ios)), + our_id_(our_node_id), + runner_(1), + destroy_indicator_(new boost::none_t) +{} template AsyncResultReturn Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, @@ -397,6 +404,7 @@ inline boost::asio::io_service& Connections::get_io_service() { return runner_.s inline void Connections::Shutdown() { get_io_service().post([=]() { + work_.reset(); acceptors_.clear(); connections_.clear(); id_to_endpoint_map_.clear(); diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc index 38547ad0..19698dfc 100644 --- a/src/maidsafe/routing/tests/routing_connections_test.cc +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -43,48 +43,48 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { bool c1_finished = false; bool c2_finished = false; - { - Address c1_id(MakeIdentity()); - Address c2_id(MakeIdentity()); + asio::io_service ios; - Connections c1(c1_id); - Connections c2(c2_id); + Address c1_id(MakeIdentity()); + Address c2_id(MakeIdentity()); - unsigned short port = 8080; + Connections c1(ios, c1_id); + Connections c2(ios, c2_id); - c1.Accept(port, nullptr, - [&](asio::error_code error, Connections::AcceptResult result) { - ASSERT_FALSE(error); - ASSERT_EQ(result.his_address, c2.OurId()); - ASSERT_EQ(result.our_endpoint.port(), port); - - c1.Send(result.his_address, - str_to_msg("hello"), - [&](asio::error_code error) { - ASSERT_FALSE(error); - c1.Shutdown(); - c1_finished = true; - }); - }); + unsigned short port = 8080; - c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), - [&](asio::error_code error, Connections::ConnectResult result) { + c1.Accept(port, nullptr, + [&](asio::error_code error, Connections::AcceptResult result) { + ASSERT_FALSE(error); + ASSERT_EQ(result.his_address, c2.OurId()); + ASSERT_EQ(result.our_endpoint.port(), port); + + c1.Send(result.his_address, + str_to_msg("hello"), + [&](asio::error_code error) { + ASSERT_FALSE(error); + c1.Shutdown(); + c1_finished = true; + }); + }); + + c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), + [&](asio::error_code error, Connections::ConnectResult result) { + ASSERT_FALSE(error); + ASSERT_EQ(result.his_address, c1.OurId()); + + c2.Receive([&, result](asio::error_code error, Connections::ReceiveResult recv_result) { ASSERT_FALSE(error); - ASSERT_EQ(result.his_address, c1.OurId()); + ASSERT_EQ(recv_result.his_address, result.his_address); + ASSERT_EQ(msg_to_str(recv_result.message), "hello"); - c2.Receive([&, result](asio::error_code error, Connections::ReceiveResult recv_result) { - ASSERT_FALSE(error); - ASSERT_EQ(recv_result.his_address, result.his_address); - ASSERT_EQ(msg_to_str(recv_result.message), "hello"); - - c2.Shutdown(); - c2_finished = true; - }); + c2.Shutdown(); + c2_finished = true; }); + }); + + ios.run(); - c1.Wait(); - c2.Wait(); - } ASSERT_TRUE(c1_finished && c2_finished); } @@ -92,8 +92,12 @@ TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { Address c1_id(MakeIdentity()); Address c2_id(MakeIdentity()); - Connections c1(c1_id); - Connections c2(c2_id); + asio::io_service ios; + + Connections c1(ios, c1_id); + Connections c2(ios, c2_id); + + std::thread thread([&]() { ios.run(); }); unsigned short port = 8080; @@ -116,6 +120,8 @@ TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { c1.Shutdown(); c2.Shutdown(); + + thread.join(); } } // namespace test From 306ae7051d073b8dc558d07444d400ac2ebacf70 Mon Sep 17 00:00:00 2001 From: prakash Date: Wed, 18 Mar 2015 15:19:21 +0000 Subject: [PATCH 43/72] sending connect to bootstrap_node if RT is empty. --- include/maidsafe/routing/routing_node.h | 37 +++++++++++++------ src/maidsafe/routing/connection_manager.h | 2 +- .../routing/tests/utils/fake_vault_facade.h | 6 +++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 9b531561..8c3bb915 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -221,8 +221,8 @@ void RoutingNode::PutOurPublicPmid() { connection_manager_.Send(*bootstrap_node_, message, [=](asio::error_code error) { if (error) LOG(kWarning) << "Failed to send to < " << *this->bootstrap_node_; - else - LOG(kVerbose) << "Sent PutOurPublicPmid to : " << *this->bootstrap_node_; + //else + //LOG(kVerbose) << "Sent PutOurPublicPmid to : " << *this->bootstrap_node_; }); }); } @@ -293,7 +293,7 @@ void RoutingNode::ConnectToCloseGroup() { FindGroup message(NodeAddress(OurId()), OurId()); MessageHeader header(DestinationAddress(std::make_pair(Destination(OurId()), boost::none)), SourceAddress{OurSourceAddress()}, ++message_id_, Authority::node); - if (bootstrap_node_) { + if (bootstrap_node_) { // TODO cleanup // this is special case , so probably have special function in connection manager to send to // bootstrap node auto msg_data = Serialise(header, MessageToTag::value(), message); @@ -301,13 +301,13 @@ void RoutingNode::ConnectToCloseGroup() { if (error) { LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); } else { - LOG(kInfo) << "Sent Find group"; +// LOG(kInfo) << "Sent Find group"; } }); return; } for (const auto& target : connection_manager_.GetTarget(OurId())) { - auto msg_data = Serialise(header, MessageToTag::value(), message); + auto msg_data = Serialise(header, MessageToTag::value(), message); connection_manager_.Send(target.id, std::move(msg_data), [](asio::error_code error) { if (error) { LOG(kWarning) << "rudp cannot send" << error.message(); @@ -317,10 +317,9 @@ void RoutingNode::ConnectToCloseGroup() { } - template void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { - LOG(kInfo) << OurId() << " MessageReceived from " << peer_id << " <<< "<< hex::Substr(serialised_message) << ">>>"; +// LOG(kInfo) << OurId() << " MessageReceived from " << peer_id << " <<< "<< hex::Substr(serialised_message) << ">>>"; InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; @@ -331,8 +330,9 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri LOG(kError) << "header failure." << boost::current_exception_diagnostic_information(); return; } - LOG(kVerbose) << "MessageReceived from " << peer_id << " PutData " << header.MessageId() - << "tag: " << static_cast::type>(tag); + LOG(kVerbose) << " [ " << OurId() << " ] "<< " Msg from [ " << peer_id + << " ] MessageId " << header.MessageId() + << " tag: " << static_cast::type>(tag); if (filter_.Check(header.FilterValue())) @@ -546,19 +546,18 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi connection_manager_.Send(node.id, message, [](asio::error_code) {}); } - LOG(kInfo) << "FindGroupResponse msg <<< "<< hex::Substr(message) << ">>>"; // if node in my group && in non routing list send it to non_routnig list as well //if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle message part ! // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? temp code to get past zero state. Delete me !! auto temp = (*original_header.ReplyToAddress()).data; - LOG(kWarning) << "FindGroupResp sent to " << temp << " but fails !!!!!!!!!!!!!!!!!!!!"; + //LOG(kVerbose) << "FindGroupResp sent to " << temp ; connection_manager_.Send(temp, message, [=](asio::error_code error) { if (error) { LOG(kWarning) << "Could not send to " << temp; } else { - LOG(kInfo) << "Sent FindGroupResponse to " << temp; + //LOG(kVerbose) << "Sent FindGroupResponse to " << temp; } }); } @@ -569,6 +568,7 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, // this is called to get our group on bootstrap, we will try and connect to each of these nodes // Only other reason is to allow the sentinel to check signatures and those calls will just fall // through here. + LOG(kInfo) << "HandleMessage -- FindGroupResponse msg"; for (const auto node_pmid : find_group_reponse.group()) { Address node_id(node_pmid.Name()); if (!connection_manager_.SuggestNodeToAdd(node_id)) @@ -576,6 +576,19 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, Connect message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); MessageHeader header(DestinationAddress(std::make_pair(Destination(node_id), boost::none)), SourceAddress{OurSourceAddress()}, ++message_id_, Authority::nae_manager); + + if (bootstrap_node_) { // TODO cleanup + auto message_data = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(*bootstrap_node_, + std::move(message_data), [](asio::error_code error) { + if (error) { + LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); + } else { + LOG(kInfo) << "Sent Connect "; + } + }); + return; + } for (const auto& target : connection_manager_.GetTarget(node_id)) { // FIXME(Team): Do the serialisation only once as it doesn't depend on the target. auto message_data = Serialise(header, MessageToTag::value(), message); diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 572f310e..4be3b5a9 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -157,7 +157,7 @@ template void ConnectionManager::Send(const Address& addr, const SerialisedMessage& message, Handler handler) { std::weak_ptr guard = connections_; - LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); +// LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); connections_->Send(addr, message, [=](asio::error_code error) { handler(error); diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index 1df83f0d..e5fa82d5 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -115,6 +115,12 @@ class FakeVaultFacade : public MaidManager, routing::Authority from_authority, routing::Authority authority, Data::NameAndTypeId name_and_type_id, SerialisedData serialised_data); + routing::HandlePutPostReturn HandlePut(routing::SourceAddress from, + routing::Authority from_authority, + routing::Destination to, + routing::Authority our_authority, + std::shared_ptr data); + bool HandlePost(const routing::SerialisedMessage& message); // not in local cache do upper layers have it (called when we are in target group) template From 3f609f69aad3b8eadce3257a909ca9064d721a5d Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 18 Mar 2015 15:39:22 +0000 Subject: [PATCH 44/72] Trivial fixes. --- src/maidsafe/routing/connection_manager.h | 2 +- .../tests/routing_connection_manager_check_in_group.cc | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 4be3b5a9..103e6afb 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -116,7 +116,7 @@ class ConnectionManager { bool CloseGroupMember(const Address& their_id); - uint32_t Size() { return routing_table_.Size(); } + std::size_t Size() { return routing_table_.Size(); } template void Send(const Address&, const SerialisedMessage&, Handler); diff --git a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc index 423f96c8..7c4cb2e6 100644 --- a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc +++ b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc @@ -16,6 +16,7 @@ See the Licences for the specific language governing permissions and limitations relating to use of the MaidSafe Software. */ +#include #include #include @@ -62,7 +63,7 @@ struct FutureHandler { NodeInfo GenerateNodeInfo() { passport::PublicPmid fob{passport::Pmid(passport::Anpmid())}; - NodeInfo node_info(NodeId(RandomString(NodeId::kSize)), fob, false); + NodeInfo node_info(MakeIdentity(), fob, false); return std::move(node_info); } @@ -73,9 +74,12 @@ EndpointPair LocalEndpointPair(unsigned short port) { TEST(ConnectionManagerTest, FUNC_AddNodes) { NodeInfo c1_info = GenerateNodeInfo(); NodeInfo c2_info = GenerateNodeInfo(); + AsioService asio_service(10); - ConnectionManager cm1(c1_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); - ConnectionManager cm2(c2_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); + ConnectionManager cm1(asio_service.service(), c1_info.id, ConnectionManager::OnReceive(), + ConnectionManager::OnConnectionLost()); + ConnectionManager cm2(asio_service.service(), c2_info.id, ConnectionManager::OnReceive(), + ConnectionManager::OnConnectionLost()); FutureHandler cm1_result("cm1"); FutureHandler cm2_result("cm2"); From 525fbe66b39399fd4810e72d1d612ae46cb54ce2 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Wed, 18 Mar 2015 17:47:41 +0000 Subject: [PATCH 45/72] Testing Put (WIP). --- include/maidsafe/routing/routing_node.h | 15 +++++------ src/maidsafe/routing/connection_manager.h | 2 +- .../tests/routing_fake_vault_facade_test.cc | 26 ++++++++++++++++--- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 8c3bb915..8e3ce7ff 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -137,7 +137,6 @@ class RoutingNode { void ConnectToCloseGroup(); Address OurId() const { return Address(our_fob_.name()); } - private: using unique_identifier = std::pair; AsioService asio_service_; passport::Pmid our_fob_; @@ -212,7 +211,7 @@ void RoutingNode::PutOurPublicPmid() { auto type_id = our_public_pmid.TypeId(); asio::post(asio_service_.service(), [=] { // FIXME(Prakash) request should be signed and may be sent to ClientManager - MessageHeader our_header(std::make_pair(Destination(Address(name)), boost::none), + MessageHeader our_header(std::make_pair(Destination(name), boost::none), OurSourceAddress(), ++message_id_, Authority::client); // As this node is not yet connected to its close group, client authority seems appropriate PutData request(type_id, Serialise(our_public_pmid)); @@ -255,15 +254,15 @@ PutReturn RoutingNode::Put(DataType data, CompletionToke PutHandler handler(std::forward(token)); asio::async_result result(handler); asio::post(asio_service_.service(), [=] { - MessageHeader our_header(std::make_pair(Destination(OurId()), boost::none), // send to ClientMgr - OurSourceAddress(), ++message_id_, Authority::client); - PutData request(DataType::Tag::kValue, data.serialise()); + MessageHeader our_header( + std::make_pair(Destination(OurId()), boost::none), // send to ClientMgr + OurSourceAddress(), ++message_id_, Authority::client); + PutData request(data.TypeId(), Serialise(data)); // FIXME(dirvine) For client in real put this needs signed :08/02/2015 - // fixme data should serialise properly and not require the above call to serialse() auto message(Serialise(our_header, MessageToTag::value(), request)); - for (const auto& target : connection_manager_.GetTarget(OurId())) { + for (const auto& target : connection_manager_.GetTarget(OurId())) connection_manager_.Send(target.id, message, [](asio::error_code) {}); - } + connection_manager_.Send(*bootstrap_node_, message, [](asio::error_code) {}); }); return result.get(); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 103e6afb..5476e0b5 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -157,7 +157,7 @@ template void ConnectionManager::Send(const Address& addr, const SerialisedMessage& message, Handler handler) { std::weak_ptr guard = connections_; -// LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); + LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); connections_->Send(addr, message, [=](asio::error_code error) { handler(error); diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index c596ec06..ca67bd65 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -16,9 +16,14 @@ See the Licences for the specific language governing permissions and limitations relating to use of the MaidSafe Software. */ -#include "maidsafe/common/test.h" #include "maidsafe/routing/tests/utils/fake_vault_facade.h" +#include "asio/spawn.hpp" + +#include "maidsafe/common/asio_service.h" +#include "maidsafe/common/test.h" +#include "maidsafe/common/data_types/immutable_data.h" + namespace maidsafe { namespace routing { @@ -27,10 +32,25 @@ namespace test { TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { vault::test::FakeVaultFacade vault1; - Sleep(std::chrono::seconds(2)); + Sleep(std::chrono::seconds(1)); vault::test::FakeVaultFacade vault2; //ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); - Sleep(std::chrono::seconds(20)); + Sleep(std::chrono::seconds(5)); + + LOG(kInfo) << "================================================================================="; + + AsioService asio_service(1); + asio::spawn(asio_service.service(), [&](asio::yield_context yield) { + std::error_code error; + vault2.Put(ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50))), yield[error]); + EXPECT_FALSE(error); + passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); + vault1.Put(passport::PublicMaid(maid_and_signer.first), yield[error]); + EXPECT_FALSE(error); + }); + + Sleep(std::chrono::seconds(1)); + asio_service.Stop(); } //TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { From 037d91bfd40e518bf6944a3c9689df92f1510d7a Mon Sep 17 00:00:00 2001 From: prakash Date: Wed, 18 Mar 2015 17:50:42 +0000 Subject: [PATCH 46/72] added utility function to SendSwarmOrParallel or SendToBootstrapNode --- include/maidsafe/routing/routing_node.h | 56 ++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 8c3bb915..5e4f067f 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -113,6 +113,13 @@ class RoutingNode { // each member of a group needs to send this to the network Address (recieveing needs a Quorum) // filling in public key again. void HandleMessage(routing::Post post, MessageHeader original_header); + + template + void SendSwarmOrParallel(const DestinationAddress& destination, const SourceAddress& source, + const MessageType& message, Authority authority); + template + void SendToBootstrapNode(const DestinationAddress& destination, const SourceAddress& source, + const MessageType& message, Authority authority); bool TryCache(MessageTypeTag tag, MessageHeader header, Address name); Authority OurAuthority(const Address& element, const MessageHeader& header) const; void MessageReceived(Address peer_id, SerialisedMessage serialised_message); @@ -467,6 +474,7 @@ void RoutingNode::ConnectionLost(boost::optional di // reply with our details; template void RoutingNode::HandleMessage(Connect connect, MessageHeader original_header) { + LOG(kInfo) << "HandleMessage -- Connect msg .. need to connect to " << connect.requester_id(); if (!connection_manager_.SuggestNodeToAdd(connect.requester_id())) return; auto targets(connection_manager_.GetTarget(connect.requester_id())); @@ -478,6 +486,17 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h SourceAddress(OurSourceAddress()), original_header.MessageId(), Authority::node, asymm::Sign(asymm::PlainText(Serialise(respond)), our_fob_.private_key())); + if (bootstrap_node_) { // TODO cleanup + auto message = Serialise(header, MessageToTag::value(), respond); + connection_manager_.Send(*bootstrap_node_, std::move(message), [](asio::error_code error) { + if (error) { + LOG(kWarning) << "Cannot send ConnectResponse via bootstrap node" << error.message(); + } else { + LOG(kInfo) << "Sent ConnectResponse"; + } + }); + return; + } // FIXME(dirvine) Do we need to pass a shared_from_this type object or this may segfault on // shutdown // :24/01/2015 @@ -523,7 +542,6 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { bootstrap_node_ = boost::none; } }); - } template @@ -646,6 +664,42 @@ SourceAddress RoutingNode::OurSourceAddress(GroupAddress group) const { return SourceAddress(NodeAddress(OurId()), group, boost::none); } + +template +template +void RoutingNode::SendSwarmOrParallel(const DestinationAddress& destination, + const SourceAddress& source, + const MessageType& message, + Authority authority) { + MessageHeader header(destination, source, ++message_id_, authority); + for (const auto& target : connection_manager_.GetTarget(destination.first.data)) { + auto wrapped_message = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(target.id, std::move(wrapped_message), [](asio::error_code error) { + if (error) { + LOG(kWarning) << "Connection manager cannot send" << error.message(); + } + }); + } +} + +template +template +void RoutingNode::SendToBootstrapNode(const DestinationAddress& destination, + const SourceAddress& source, + const MessageType& message, + Authority authority) { + //assert(source.SourceAddress()== NodeAddress(*bootstrap_node_)); //FIXME(prakash) + MessageHeader header(destination, source, ++message_id_, authority); + auto wrapped_message = Serialise(header, MessageToTag::value(), message); + connection_manager_.Send(*bootstrap_node_, std::move(wrapped_message), + [](asio::error_code error) { + if (error) { + LOG(kWarning) << "Connection manager cannot send to bootstrap node" + << error.message(); + } + }); +} + } // namespace routing } // namespace maidsafe From 5fc10fab54c943924e89ac559eb0821e5b241166 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 18 Mar 2015 14:43:46 +0100 Subject: [PATCH 47/72] Compilation fixes --- src/maidsafe/routing/connections.h | 8 +------- ...outing_connection_manager_check_in_group.cc | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index bda2096b..e6038464 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -95,8 +95,6 @@ class Connections { boost::asio::io_service& get_io_service(); - std::weak_ptr Guard() { return destroy_indicator_; } - void Wait(); private: @@ -131,16 +129,13 @@ class Connections { std::queue receive_output_; BoostAsioService runner_; - - std::shared_ptr destroy_indicator_; }; inline Connections::Connections(asio::io_service& ios, const Address& our_node_id) : service(ios), work_(new asio::io_service::work(ios)), our_id_(our_node_id), - runner_(1), - destroy_indicator_(new boost::none_t) + runner_(1) {} template @@ -215,7 +210,6 @@ inline void Connections::OnReceive(asio::error_code error, ReceiveResult result) } inline Connections::~Connections() { - destroy_indicator_.reset(); Shutdown(); runner_.Stop(); } diff --git a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc index 423f96c8..75c98999 100644 --- a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc +++ b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc @@ -18,6 +18,7 @@ #include #include +#include #include "maidsafe/common/rsa.h" #include "maidsafe/common/test.h" @@ -62,7 +63,7 @@ struct FutureHandler { NodeInfo GenerateNodeInfo() { passport::PublicPmid fob{passport::Pmid(passport::Anpmid())}; - NodeInfo node_info(NodeId(RandomString(NodeId::kSize)), fob, false); + NodeInfo node_info(MakeIdentity(), fob, false); return std::move(node_info); } @@ -74,8 +75,13 @@ TEST(ConnectionManagerTest, FUNC_AddNodes) { NodeInfo c1_info = GenerateNodeInfo(); NodeInfo c2_info = GenerateNodeInfo(); - ConnectionManager cm1(c1_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); - ConnectionManager cm2(c2_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); + asio::io_service ios; + auto work = std::make_shared(ios); + + ConnectionManager cm1(ios, c1_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); + ConnectionManager cm2(ios, c2_info.id, ConnectionManager::OnReceive(), ConnectionManager::OnConnectionLost()); + + std::thread thread([&]() { ios.run(); }); FutureHandler cm1_result("cm1"); FutureHandler cm2_result("cm2"); @@ -85,6 +91,12 @@ TEST(ConnectionManagerTest, FUNC_AddNodes) { cm1_result.Get(); cm2_result.Get(); + + cm1.Shutdown(); + cm2.Shutdown(); + + work.reset(); + thread.join(); } TEST(ConnectionManagerTest, FUNC_AddNodesCheckCloseGroup) { From 12124f78b1752187856914e3e6078eb2c6e11df1 Mon Sep 17 00:00:00 2001 From: prakash Date: Thu, 19 Mar 2015 00:43:47 +0000 Subject: [PATCH 48/72] further cleanup --- include/maidsafe/routing/routing_node.h | 72 ++++++------------------- 1 file changed, 17 insertions(+), 55 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 5e4f067f..aef5c95b 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -219,18 +219,9 @@ void RoutingNode::PutOurPublicPmid() { auto type_id = our_public_pmid.TypeId(); asio::post(asio_service_.service(), [=] { // FIXME(Prakash) request should be signed and may be sent to ClientManager - MessageHeader our_header(std::make_pair(Destination(Address(name)), boost::none), - OurSourceAddress(), ++message_id_, Authority::client); - // As this node is not yet connected to its close group, client authority seems appropriate - PutData request(type_id, Serialise(our_public_pmid)); - - auto message(Serialise(our_header, MessageToTag::value(), request)); - connection_manager_.Send(*bootstrap_node_, message, [=](asio::error_code error) { - if (error) - LOG(kWarning) << "Failed to send to < " << *this->bootstrap_node_; - //else - //LOG(kVerbose) << "Sent PutOurPublicPmid to : " << *this->bootstrap_node_; - }); + PutData put_data_message(type_id, Serialise(our_public_pmid)); + SendToBootstrapNode(std::make_pair(Destination(Address(name)), boost::none), + OurSourceAddress(), put_data_message, Authority::client); }); } @@ -297,29 +288,13 @@ PostReturn RoutingNode::Post(Address to, FunctorType fun template void RoutingNode::ConnectToCloseGroup() { - FindGroup message(NodeAddress(OurId()), OurId()); - MessageHeader header(DestinationAddress(std::make_pair(Destination(OurId()), boost::none)), - SourceAddress{OurSourceAddress()}, ++message_id_, Authority::node); + FindGroup find_group_message(NodeAddress(OurId()), OurId()); if (bootstrap_node_) { // TODO cleanup - // this is special case , so probably have special function in connection manager to send to - // bootstrap node - auto msg_data = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(*bootstrap_node_, std::move(msg_data), [](asio::error_code error) { - if (error) { - LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); - } else { -// LOG(kInfo) << "Sent Find group"; - } - }); - return; - } - for (const auto& target : connection_manager_.GetTarget(OurId())) { - auto msg_data = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(target.id, std::move(msg_data), [](asio::error_code error) { - if (error) { - LOG(kWarning) << "rudp cannot send" << error.message(); - } - }); + SendToBootstrapNode(std::make_pair(Destination(OurId()), boost::none), + OurSourceAddress(), find_group_message, Authority::node); + } else { + SendSwarmOrParallel(std::make_pair(Destination(OurId()), boost::none), + OurSourceAddress(), find_group_message, Authority::node); } } @@ -591,26 +566,13 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, Address node_id(node_pmid.Name()); if (!connection_manager_.SuggestNodeToAdd(node_id)) continue; - Connect message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); - MessageHeader header(DestinationAddress(std::make_pair(Destination(node_id), boost::none)), - SourceAddress{OurSourceAddress()}, ++message_id_, Authority::nae_manager); - + Connect connect_message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); if (bootstrap_node_) { // TODO cleanup - auto message_data = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(*bootstrap_node_, - std::move(message_data), [](asio::error_code error) { - if (error) { - LOG(kWarning) << "Cannot send via bootstrap node" << error.message(); - } else { - LOG(kInfo) << "Sent Connect "; - } - }); - return; - } - for (const auto& target : connection_manager_.GetTarget(node_id)) { - // FIXME(Team): Do the serialisation only once as it doesn't depend on the target. - auto message_data = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(target.id, std::move(message_data), [](asio::error_code) {}); + SendToBootstrapNode(std::make_pair(Destination(node_id), boost::none), + OurSourceAddress(), connect_message, Authority::nae_manager); + } else { + SendSwarmOrParallel(std::make_pair(Destination(node_id), boost::none), + OurSourceAddress(), connect_message, Authority::nae_manager); } } } @@ -673,7 +635,7 @@ void RoutingNode::SendSwarmOrParallel(const DestinationAddress& destinati Authority authority) { MessageHeader header(destination, source, ++message_id_, authority); for (const auto& target : connection_manager_.GetTarget(destination.first.data)) { - auto wrapped_message = Serialise(header, MessageToTag::value(), message); + auto wrapped_message = Serialise(header, MessageToTag::value(), message); connection_manager_.Send(target.id, std::move(wrapped_message), [](asio::error_code error) { if (error) { LOG(kWarning) << "Connection manager cannot send" << error.message(); @@ -690,7 +652,7 @@ void RoutingNode::SendToBootstrapNode(const DestinationAddress& destinati Authority authority) { //assert(source.SourceAddress()== NodeAddress(*bootstrap_node_)); //FIXME(prakash) MessageHeader header(destination, source, ++message_id_, authority); - auto wrapped_message = Serialise(header, MessageToTag::value(), message); + auto wrapped_message = Serialise(header, MessageToTag::value(), message); connection_manager_.Send(*bootstrap_node_, std::move(wrapped_message), [](asio::error_code error) { if (error) { From 7680e4d60527800c3506e8c925b3d76440e6c94d Mon Sep 17 00:00:00 2001 From: prakash Date: Thu, 19 Mar 2015 02:40:26 +0000 Subject: [PATCH 49/72] temp code --- include/maidsafe/routing/routing_node.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index aef5c95b..25088bf6 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -481,6 +481,20 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h connection_manager_.Send(target.id, std::move(message), [](asio::error_code) {}); } + //////////////////////// temp code Delete me + + auto temp = (*original_header.ReplyToAddress()).data; + auto message = Serialise(header, MessageToTag::value(), respond); + connection_manager_.Send(temp, message, + [=](asio::error_code error) { + if (error) { + LOG(kWarning) << "Could not send to " << temp; + } else { + LOG(kVerbose) << "Sent ConnectResponse to " << temp; + } + }); + //////////////////////// + std::weak_ptr destroy_guard = destroy_indicator_; connection_manager_.AddNodeAccept @@ -495,6 +509,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h template void RoutingNode::HandleMessage(ConnectResponse connect_response) { +LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " << connect_response.receiver_id(); if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) return; From b8a5c97d6e8f02fcb0ea2eba69f29ef3cbce5d1e Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Fri, 20 Mar 2015 02:06:25 +0100 Subject: [PATCH 50/72] AddNode handler arguments now contain an error_code Also AddNodeAccept now times out --- include/maidsafe/routing/routing_node.h | 10 ++- src/maidsafe/routing/connection_manager.cc | 44 ++++++++-- src/maidsafe/routing/connection_manager.h | 7 +- ...uting_connection_manager_check_in_group.cc | 5 +- src/maidsafe/routing/timer.h | 83 +++++++++++++++++++ 5 files changed, 134 insertions(+), 15 deletions(-) create mode 100644 src/maidsafe/routing/timer.h diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index d46fa6ca..53e37bd0 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -494,9 +494,10 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h connection_manager_.AddNodeAccept (NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints(), - [=](boost::optional added, Endpoint /* our_endpoint */) { + [=](asio::error_code error, boost::optional added, + Endpoint /* our_endpoint */) { if (!destroy_guard.lock()) return; - if (added) + if (!error && added) static_cast(this)->HandleChurn(*added); }); } @@ -514,11 +515,12 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { connection_manager_.AddNode( NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), response_ptr->receiver_endpoints(), - [=](boost::optional added, Endpoint /* our_endpoint */) { + [=](asio::error_code error, boost::optional added, + Endpoint /* our_endpoint */) { if (!destroy_guard.lock()) return; auto target = response_ptr->requester_id(); - if (added) + if (!error && added) static_cast(this)->HandleChurn(*added); if (connection_manager_.Size() >= QuorumSize) { // rudp_.Remove(*bootstrap_node_, asio::use_future).get(); // FIXME (Prakash) diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 882c6294..1e52b652 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -31,6 +31,7 @@ #include "maidsafe/routing/peer_node.h" #include "maidsafe/routing/routing_table.h" +#include "maidsafe/routing/timer.h" #include "maidsafe/routing/types.h" namespace maidsafe { @@ -45,14 +46,15 @@ using boost::optional; ConnectionManager::ConnectionManager(asio::io_service& ios, Address our_id, OnReceive on_receive, OnConnectionLost on_connection_lost) - : mutex_(), + : io_service_(ios), + mutex_(), our_accept_port_(5483), routing_table_(our_id), connected_non_routing_nodes_(), on_receive_(std::move(on_receive)), on_connection_lost_(std::move(on_connection_lost)), current_close_group_(), - connections_(new Connections(ios, our_id)) { + connections_(new Connections(io_service_, our_id)) { StartReceiving(); StartAccepting(); } @@ -126,7 +128,9 @@ void ConnectionManager::HandleAccept(Connections::AcceptResult result) { auto expected = std::move(expected_i->second); expected_accepts_.erase(expected_i); - expected.handler(AddToRoutingTable(std::move(expected.node_info)), result.our_endpoint); + expected.handler(asio::error_code(), + AddToRoutingTable(std::move(expected.node_info)), + result.our_endpoint); } else { connected_non_routing_nodes_.insert(result.his_address); @@ -135,11 +139,33 @@ void ConnectionManager::HandleAccept(Connections::AcceptResult result) { void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, OnAddNode on_node_added) { - // TODO(PeterJ): Use internal endpoint as well. - expected_accepts_.insert(std::make_pair(node_info.id, ExpectedAccept{node_info, on_node_added})); - //StartAccepting(connections_, node_to_add, their_endpoint_pair, [=](Endpoint our_endpoint) { - // on_node_added(AddToRoutingTable(node_to_add), our_endpoint); - //}); + auto id = node_info.id; + + auto timer = std::make_shared(io_service_); + + auto canceling_handler = [on_node_added, timer] + (asio::error_code error, boost::optional diff, + Endpoint endpoint) { + timer->cancel(); + on_node_added(error, std::move(diff), endpoint); + }; + + auto insert_result = expected_accepts_.insert + (std::make_pair(id, + ExpectedAccept{node_info, + canceling_handler, + timer})); + + if (!insert_result.second) { + return io_service_.post([on_node_added]() { + on_node_added(asio::error::already_started, boost::none, Endpoint()); + }); + } + + timer->async_wait(std::chrono::seconds(10), [=]() { + expected_accepts_.erase(id); + on_node_added(asio::error::timed_out, boost::none, Endpoint()); + }); } void ConnectionManager::AddNode( @@ -157,7 +183,7 @@ void ConnectionManager::AddNode( if (error || (result.his_address != node_to_add.id)) { return; } - on_node_added(AddToRoutingTable(node_to_add), result.our_endpoint); + on_node_added(asio::error_code(), AddToRoutingTable(node_to_add), result.our_endpoint); }); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 572f310e..852b652c 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -58,18 +58,22 @@ namespace maidsafe { namespace routing { +class Timer; + class ConnectionManager { using PublicPmid = passport::PublicPmid; public: using OnReceive = std::function; - using OnAddNode = std::function, Endpoint)>; + using OnAddNode = std::function, + Endpoint)>; using OnConnectionLost = std::function, Address)>; private: struct ExpectedAccept { NodeInfo node_info; OnAddNode handler; + std::shared_ptr timer; }; public: @@ -142,6 +146,7 @@ class ConnectionManager { private: + asio::io_service& io_service_; mutable std::mutex mutex_; unsigned short our_accept_port_; RoutingTable routing_table_; diff --git a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc index 75c98999..b9f741b8 100644 --- a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc +++ b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc @@ -54,7 +54,10 @@ struct FutureHandler { FutureHandler(std::string what) : what(std::move(what)), state(std::make_shared()) {} - void operator()(Value v, Endpoint) const { + void operator()(asio::error_code error, Value v, Endpoint) const { + if (error) { + throw std::runtime_error("operation failed"); + } state->promise.set_value(std::move(v)); } diff --git a/src/maidsafe/routing/timer.h b/src/maidsafe/routing/timer.h new file mode 100644 index 00000000..d3eea092 --- /dev/null +++ b/src/maidsafe/routing/timer.h @@ -0,0 +1,83 @@ +/* Copyright 2014 MaidSafe.net limited + + This MaidSafe Software is licensed to you under (1) the MaidSafe.net Commercial License, + version 1.0 or later, or (2) The General Public License (GPL), version 3, depending on which + licence you accepted on initial access to the Software (the "Licences"). + + By contributing code to the MaidSafe Software, or to this project generally, you agree to be + bound by the terms of the MaidSafe Contributor Agreement, version 1.0, found in the root + directory of this project at LICENSE, COPYING and CONTRIBUTOR respectively and also + available at: http://www.maidsafe.net/licenses + + Unless required by applicable law or agreed to in writing, the MaidSafe Software distributed + under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS + OF ANY KIND, either express or implied. + + See the Licences for the specific language governing permissions and limitations relating to + use of the MaidSafe Software. */ + +#ifndef MAIDSAFE_ROUTING_TIMER_H_ +#define MAIDSAFE_ROUTING_TIMER_H_ + +#include +#include +#include "asio/steady_timer.hpp" + +namespace maidsafe +{ + +namespace routing +{ + +class Timer { + enum State { idle, running, canceled }; + + public: + Timer(asio::io_service&); + ~Timer(); + + template + void async_wait(asio::steady_timer::duration, Handler&&); + + void cancel(); + + private: + asio::steady_timer timer_; + std::shared_ptr state_; +}; + +inline Timer::Timer(asio::io_service& ios) + : timer_(ios), + state_(std::make_shared(idle)) +{} + +inline Timer::~Timer() { + cancel(); +} + +template +void Timer::async_wait(asio::steady_timer::duration duration, Handler&& handler) { + auto state = state_; + assert(*state == idle && "Current implementation allows only one async_wait invocation"); + *state = running; + timer_.expires_from_now(duration); + // FIXME(Team): forward the handler if we're using c++14 + timer_.async_wait([state, handler](const asio::error_code&) { + if (*state != running) { + return; + } + handler(); + }); +} + +inline void Timer::cancel() { + *state_ = canceled; + timer_.cancel(); +} + +} // routing namespace + +} // maidsafe namespace + +#endif // MAIDSAFE_ROUTING_TIMER_H_ + From 5dc46df34a4d61226e4e6add8643b45eb301ab80 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Fri, 20 Mar 2015 15:30:09 +0100 Subject: [PATCH 51/72] Node is added into routing table even if connect timed out Also a bit of refactoring. --- include/maidsafe/routing/routing_node.h | 6 +- src/maidsafe/routing/connection_manager.cc | 89 ++++++++++--------- src/maidsafe/routing/connection_manager.h | 6 +- ...uting_connection_manager_check_in_group.cc | 2 +- .../tests/routing_fake_vault_facade_test.cc | 1 - 5 files changed, 54 insertions(+), 50 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 53e37bd0..3d2f21d5 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -494,8 +494,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h connection_manager_.AddNodeAccept (NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints(), - [=](asio::error_code error, boost::optional added, - Endpoint /* our_endpoint */) { + [=](asio::error_code error, boost::optional added) { if (!destroy_guard.lock()) return; if (!error && added) static_cast(this)->HandleChurn(*added); @@ -515,8 +514,7 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { connection_manager_.AddNode( NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), response_ptr->receiver_endpoints(), - [=](asio::error_code error, boost::optional added, - Endpoint /* our_endpoint */) { + [=](asio::error_code error, boost::optional added) { if (!destroy_guard.lock()) return; auto target = response_ptr->requester_id(); diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 1e52b652..27849a4c 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -94,47 +94,53 @@ void ConnectionManager::DropNode(const Address& their_id) { void ConnectionManager::StartAccepting() { std::weak_ptr weak_connections = connections_; - auto accept_handler = [=](asio::error_code error, Connections::AcceptResult result) { - auto connections = weak_connections.lock(); - - if (!connections) { + connections_->Accept( our_accept_port_ + , &our_accept_port_ + , [=](asio::error_code error, Connections::AcceptResult result) { + if (!weak_connections.lock()) { return; } - if (error == asio::error::operation_aborted || error == asio::error::already_started) { - return; - } + auto expected_i = expected_accepts_.find(result.his_address); - if (!error) { - HandleAccept(std::move(result)); + if (expected_i != expected_accepts_.end()) { + auto expected = std::move(expected_i->second); + expected_accepts_.erase(expected_i); + + HandleAddNode( error + , std::move(expected.node_info) + , std::move(expected.handler)); // The handler may have destroyed 'this'. if (!weak_connections.lock()) { return; } } + else { + if (!error) { + connected_non_routing_nodes_.insert(result.his_address); + } + } - return StartAccepting(); - }; + if (error != asio::error::operation_aborted) { + StartAccepting(); + } + }); - connections_->Accept(our_accept_port_, &our_accept_port_, std::move(accept_handler)); LOG(kInfo) << "StartAccepting() port " << our_accept_port_; } -void ConnectionManager::HandleAccept(Connections::AcceptResult result) { - auto expected_i = expected_accepts_.find(result.his_address); +void ConnectionManager::HandleAddNode( asio::error_code error + , NodeInfo node_info + , OnAddNode user_handler) +{ + if (error && error != asio::error::timed_out) { + return; + } - if (expected_i != expected_accepts_.end()) { - auto expected = std::move(expected_i->second); - expected_accepts_.erase(expected_i); + node_info.connected = error != asio::error::timed_out; - expected.handler(asio::error_code(), - AddToRoutingTable(std::move(expected.node_info)), - result.our_endpoint); - } - else { - connected_non_routing_nodes_.insert(result.his_address); - } + user_handler(error, AddToRoutingTable(std::move(node_info))); } void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, @@ -143,47 +149,50 @@ void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, auto timer = std::make_shared(io_service_); - auto canceling_handler = [on_node_added, timer] - (asio::error_code error, boost::optional diff, - Endpoint endpoint) { + auto canceling_handler = [on_node_added, timer]( asio::error_code error + , boost::optional diff) { timer->cancel(); - on_node_added(error, std::move(diff), endpoint); + on_node_added(error, std::move(diff)); }; auto insert_result = expected_accepts_.insert (std::make_pair(id, ExpectedAccept{node_info, - canceling_handler, - timer})); + canceling_handler})); if (!insert_result.second) { return io_service_.post([on_node_added]() { - on_node_added(asio::error::already_started, boost::none, Endpoint()); + on_node_added(asio::error::already_started, boost::none); }); } + // TODO(Team): Is the timeout value correct? Should it be in defined + // somewhere else? timer->async_wait(std::chrono::seconds(10), [=]() { expected_accepts_.erase(id); - on_node_added(asio::error::timed_out, boost::none, Endpoint()); + HandleAddNode(asio::error::timed_out, node_info, on_node_added); }); } -void ConnectionManager::AddNode( - NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode on_node_added) { +void ConnectionManager::AddNode( NodeInfo node_to_add + , EndpointPair their_endpoint_pair + , OnAddNode on_node_added) { std::weak_ptr weak_connections = connections_; // TODO(PeterJ): Use local endpoint as well - connections_->Connect(their_endpoint_pair.external, - [=](asio::error_code error, Connections::ConnectResult result) { + connections_->Connect( their_endpoint_pair.external + , [=]( asio::error_code error + , Connections::ConnectResult result) { if (!weak_connections.lock()) { - return; + return on_node_added(asio::error::operation_aborted, boost::none); } - if (error || (result.his_address != node_to_add.id)) { - return; + if (!error && (result.his_address != node_to_add.id)) { + error = asio::error::fault; } - on_node_added(asio::error_code(), AddToRoutingTable(node_to_add), result.our_endpoint); + + HandleAddNode(error, node_to_add, on_node_added); }); } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index 852b652c..a7add013 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -65,15 +65,13 @@ class ConnectionManager { public: using OnReceive = std::function; - using OnAddNode = std::function, - Endpoint)>; + using OnAddNode = std::function)>; using OnConnectionLost = std::function, Address)>; private: struct ExpectedAccept { NodeInfo node_info; OnAddNode handler; - std::shared_ptr timer; }; public: @@ -139,7 +137,7 @@ class ConnectionManager { void StartReceiving(); void StartAccepting(); - void HandleAccept(Connections::AcceptResult); + void HandleAddNode(asio::error_code, NodeInfo, OnAddNode); void HandleConnectionLost(Address); boost::optional GroupChanged(); diff --git a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc index b9f741b8..b546687a 100644 --- a/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc +++ b/src/maidsafe/routing/tests/routing_connection_manager_check_in_group.cc @@ -54,7 +54,7 @@ struct FutureHandler { FutureHandler(std::string what) : what(std::move(what)), state(std::make_shared()) {} - void operator()(asio::error_code error, Value v, Endpoint) const { + void operator()(asio::error_code error, Value v) const { if (error) { throw std::runtime_error("operation failed"); } diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index c596ec06..6cf9522b 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -27,7 +27,6 @@ namespace test { TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { vault::test::FakeVaultFacade vault1; - Sleep(std::chrono::seconds(2)); vault::test::FakeVaultFacade vault2; //ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); Sleep(std::chrono::seconds(20)); From 7d091da39c0347c96ba34461cc969719df820842 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 20 Mar 2015 15:12:58 +0000 Subject: [PATCH 52/72] Ran clang-format. --- include/maidsafe/routing/routing_node.h | 191 +++++++++++---------- src/maidsafe/routing/connection_manager.cc | 103 +++++------ src/maidsafe/routing/connection_manager.h | 34 ++-- src/maidsafe/routing/connections.h | 112 ++++++------ src/maidsafe/routing/timer.h | 42 ++--- 5 files changed, 225 insertions(+), 257 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 601c315b..68ff5db2 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -186,21 +186,21 @@ RoutingNode::RoutingNode() template void RoutingNode::StartBootstrap() { auto handler = [=](asio::error_code error, Address peer_addr, Endpoint /*our_public_endpoint*/) { - if (error) { - LOG(kWarning) << "Cannot connect to bootstrap endpoint < " << peer_addr - << " >" << error.message(); - // TODO(Team): try connect to bootstrap contacts and other options - // (hardcoded endpoints).on failure keep retrying all options forever - return; - } - LOG(kInfo) << "Bootstrapped with " << peer_addr; - // FIXME(Team): Thread safety. - bootstrap_node_ = peer_addr; - // bootstrap_endpoint_ = our_endpoint; this will not required if - // connection manager has this connection - PutOurPublicPmid(); - ConnectToCloseGroup(); - }; + if (error) { + LOG(kWarning) << "Cannot connect to bootstrap endpoint < " << peer_addr << " >" + << error.message(); + // TODO(Team): try connect to bootstrap contacts and other options + // (hardcoded endpoints).on failure keep retrying all options forever + return; + } + LOG(kInfo) << "Bootstrapped with " << peer_addr; + // FIXME(Team): Thread safety. + bootstrap_node_ = peer_addr; + // bootstrap_endpoint_ = our_endpoint; this will not required if + // connection manager has this connection + PutOurPublicPmid(); + ConnectToCloseGroup(); + }; // try connect to any local nodes (5483) Expect to be told Node_Id Endpoint live_port_ep(GetLocalIp(), kLivePort); // skip trying to bootstrap off self @@ -213,14 +213,14 @@ void RoutingNode::StartBootstrap() { template void RoutingNode::PutOurPublicPmid() { assert(bootstrap_node_); - passport::PublicPmid our_public_pmid{ passport::PublicPmid(our_fob_) }; + passport::PublicPmid our_public_pmid{passport::PublicPmid(our_fob_)}; auto name = our_public_pmid.Name(); auto type_id = our_public_pmid.TypeId(); asio::post(asio_service_.service(), [=] { // FIXME(Prakash) request should be signed and may be sent to ClientManager PutData put_data_message(type_id, Serialise(our_public_pmid)); - SendToBootstrapNode(std::make_pair(Destination(Address(name)), boost::none), - OurSourceAddress(), put_data_message, Authority::client); + SendToBootstrapNode(std::make_pair(Destination(Address(name)), boost::none), OurSourceAddress(), + put_data_message, Authority::client); }); } @@ -289,30 +289,31 @@ template void RoutingNode::ConnectToCloseGroup() { FindGroup find_group_message(NodeAddress(OurId()), OurId()); if (bootstrap_node_) { // TODO cleanup - SendToBootstrapNode(std::make_pair(Destination(OurId()), boost::none), - OurSourceAddress(), find_group_message, Authority::node); + SendToBootstrapNode(std::make_pair(Destination(OurId()), boost::none), OurSourceAddress(), + find_group_message, Authority::node); } else { - SendSwarmOrParallel(std::make_pair(Destination(OurId()), boost::none), - OurSourceAddress(), find_group_message, Authority::node); + SendSwarmOrParallel(std::make_pair(Destination(OurId()), boost::none), OurSourceAddress(), + find_group_message, Authority::node); } } template void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { -// LOG(kInfo) << OurId() << " MessageReceived from " << peer_id << " <<< "<< hex::Substr(serialised_message) << ">>>"; + // LOG(kInfo) << OurId() << " MessageReceived from " << peer_id << " <<< "<< + // hex::Substr(serialised_message) << ">>>"; InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; - //Identity name; + // Identity name; try { Parse(binary_input_stream, header, tag); } catch (const std::exception&) { LOG(kError) << "header failure." << boost::current_exception_diagnostic_information(); return; } - LOG(kVerbose) << " [ " << OurId() << " ] "<< " Msg from [ " << peer_id - << " ] MessageId " << header.MessageId() + LOG(kVerbose) << " [ " << OurId() << " ] " + << " Msg from [ " << peer_id << " ] MessageId " << header.MessageId() << " tag: " << static_cast::type>(tag); @@ -355,14 +356,15 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri } }); } - if (header.RelayedMessage() && (header.FromNode().data != OurId())) { // skip outgoing msgs - std::set
connected_non_routing_nodes{ connection_manager_.GetNonRoutingNodes() }; - if (std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), - [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; })) { - // send message to connected node - connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); - return; - } + if (header.RelayedMessage() && (header.FromNode().data != OurId())) { // skip outgoing msgs + std::set
connected_non_routing_nodes{connection_manager_.GetNonRoutingNodes()}; + if (std::any_of( + std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), + [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; })) { + // send message to connected node + connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); + return; + } } if (!connection_manager_.AddressInCloseGroupRange(header.Destination().first)) { @@ -380,9 +382,9 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri } // FIXME(dirvine) Sentinel check here!! :19/01/2015 -// auto result = sentinel_.Add(header, tag, serialised_message); -// if (!result) -// return; + // auto result = sentinel_.Add(header, tag, serialised_message); + // if (!result) + // return; switch (tag) { case MessageTypeTag::Connect: @@ -440,7 +442,7 @@ Authority RoutingNode::OurAuthority(const Address& element, template void RoutingNode::ConnectionLost(boost::optional diff, Address) { - //auto change = connection_manager_.LostNetworkConnection(peer); + // auto change = connection_manager_.LostNetworkConnection(peer); if (diff) static_cast(this)->HandleChurn(*diff); } @@ -480,35 +482,36 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h connection_manager_.Send(target.id, std::move(message), [](asio::error_code) {}); } - //////////////////////// temp code Delete me - - auto temp = (*original_header.ReplyToAddress()).data; - auto message = Serialise(header, MessageToTag::value(), respond); - connection_manager_.Send(temp, message, - [=](asio::error_code error) { - if (error) { - LOG(kWarning) << "Could not send to " << temp; - } else { - LOG(kVerbose) << "Sent ConnectResponse to " << temp; - } - }); + //////////////////////// temp code Delete me + + auto temp = (*original_header.ReplyToAddress()).data; + auto message = Serialise(header, MessageToTag::value(), respond); + connection_manager_.Send(temp, message, [=](asio::error_code error) { + if (error) { + LOG(kWarning) << "Could not send to " << temp; + } else { + LOG(kVerbose) << "Sent ConnectResponse to " << temp; + } + }); //////////////////////// std::weak_ptr destroy_guard = destroy_indicator_; - connection_manager_.AddNodeAccept - (NodeInfo(connect.requester_id(), connect.requester_fob(), true), - connect.requester_endpoints(), - [=](asio::error_code error, boost::optional added) { - if (!destroy_guard.lock()) return; - if (!error && added) - static_cast(this)->HandleChurn(*added); - }); + connection_manager_.AddNodeAccept( + NodeInfo(connect.requester_id(), connect.requester_fob(), true), + connect.requester_endpoints(), + [=](asio::error_code error, boost::optional added) { + if (!destroy_guard.lock()) + return; + if (!error && added) + static_cast(this)->HandleChurn(*added); + }); } template void RoutingNode::HandleMessage(ConnectResponse connect_response) { -LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " << connect_response.receiver_id(); + LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " + << connect_response.receiver_id(); if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) return; @@ -521,7 +524,8 @@ LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " << c NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), response_ptr->receiver_endpoints(), [=](asio::error_code error, boost::optional added) { - if (!destroy_guard.lock()) return; + if (!destroy_guard.lock()) + return; auto target = response_ptr->requester_id(); if (!error && added) @@ -554,19 +558,20 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi } // if node in my group && in non routing list send it to non_routnig list as well - //if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle message part ! + // if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle + // message part ! - // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? temp code to get past zero state. Delete me !! + // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? temp code to get past zero + // state. Delete me !! auto temp = (*original_header.ReplyToAddress()).data; - //LOG(kVerbose) << "FindGroupResp sent to " << temp ; - connection_manager_.Send(temp, message, - [=](asio::error_code error) { - if (error) { - LOG(kWarning) << "Could not send to " << temp; - } else { - //LOG(kVerbose) << "Sent FindGroupResponse to " << temp; - } - }); + // LOG(kVerbose) << "FindGroupResp sent to " << temp ; + connection_manager_.Send(temp, message, [=](asio::error_code error) { + if (error) { + LOG(kWarning) << "Could not send to " << temp; + } else { + // LOG(kVerbose) << "Sent FindGroupResponse to " << temp; + } + }); } template @@ -575,18 +580,18 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, // this is called to get our group on bootstrap, we will try and connect to each of these nodes // Only other reason is to allow the sentinel to check signatures and those calls will just fall // through here. - LOG(kInfo) << "HandleMessage -- FindGroupResponse msg"; + LOG(kInfo) << "HandleMessage -- FindGroupResponse msg"; for (const auto node_pmid : find_group_reponse.group()) { Address node_id(node_pmid.Name()); if (!connection_manager_.SuggestNodeToAdd(node_id)) continue; Connect connect_message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); if (bootstrap_node_) { // TODO cleanup - SendToBootstrapNode(std::make_pair(Destination(node_id), boost::none), - OurSourceAddress(), connect_message, Authority::nae_manager); + SendToBootstrapNode(std::make_pair(Destination(node_id), boost::none), OurSourceAddress(), + connect_message, Authority::nae_manager); } else { - SendSwarmOrParallel(std::make_pair(Destination(node_id), boost::none), - OurSourceAddress(), connect_message, Authority::nae_manager); + SendSwarmOrParallel(std::make_pair(Destination(node_id), boost::none), OurSourceAddress(), + connect_message, Authority::nae_manager); } } } @@ -595,8 +600,7 @@ template void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { auto result = static_cast(this)->HandleGet( header.Source(), header.FromAuthority(), - OurAuthority(get_data.name_and_type_id().name, header), - get_data.name_and_type_id()); + OurAuthority(get_data.name_and_type_id().name, header), get_data.name_and_type_id()); if (!result) { // send back error return; @@ -611,12 +615,12 @@ void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { template void RoutingNode::HandleMessage(PutData put_data, MessageHeader /*original_header*/) { // FIXME(Prakash) -// cache_.Add(put_data.name_and_type_id().name, *put_data.data()); + // cache_.Add(put_data.name_and_type_id().name, *put_data.data()); LOG(kVerbose) << "Put Data : " << put_data.type_id(); -// auto result = static_cast(this)->HandlePut( -// original_header.Source(), original_header.FromAuthority(), -// OurAuthority(put_data.name_and_type_id().name, original_header), -// put_data.name_and_type_id(), put_data.data()); + // auto result = static_cast(this)->HandlePut( + // original_header.Source(), original_header.FromAuthority(), + // OurAuthority(put_data.name_and_type_id().name, original_header), + // put_data.name_and_type_id(), put_data.data()); } template @@ -645,8 +649,7 @@ template template void RoutingNode::SendSwarmOrParallel(const DestinationAddress& destination, const SourceAddress& source, - const MessageType& message, - Authority authority) { + const MessageType& message, Authority authority) { MessageHeader header(destination, source, ++message_id_, authority); for (const auto& target : connection_manager_.GetTarget(destination.first.data)) { auto wrapped_message = Serialise(header, MessageToTag::value(), message); @@ -662,18 +665,16 @@ template template void RoutingNode::SendToBootstrapNode(const DestinationAddress& destination, const SourceAddress& source, - const MessageType& message, - Authority authority) { - //assert(source.SourceAddress()== NodeAddress(*bootstrap_node_)); //FIXME(prakash) + const MessageType& message, Authority authority) { + // assert(source.SourceAddress()== NodeAddress(*bootstrap_node_)); //FIXME(prakash) MessageHeader header(destination, source, ++message_id_, authority); auto wrapped_message = Serialise(header, MessageToTag::value(), message); - connection_manager_.Send(*bootstrap_node_, std::move(wrapped_message), - [](asio::error_code error) { - if (error) { - LOG(kWarning) << "Connection manager cannot send to bootstrap node" - << error.message(); - } - }); + connection_manager_.Send( + *bootstrap_node_, std::move(wrapped_message), [](asio::error_code error) { + if (error) { + LOG(kWarning) << "Connection manager cannot send to bootstrap node" << error.message(); + } + }); } } // namespace routing diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 5174315b..5d09927f 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -65,9 +65,9 @@ bool ConnectionManager::SuggestNodeToAdd(const Address& node_to_add) const { std::vector ConnectionManager::GetTarget(const Address& target_node) const { auto nodes(routing_table_.TargetNodes(target_node)); - nodes.erase(std::remove_if(std::begin(nodes), std::end(nodes), - [](NodeInfo& node) { return !node.connected; }), - std::end(nodes)); + nodes.erase(std::remove_if(std::begin(nodes), std::end(nodes), [](NodeInfo& node) { + return !node.connected; + }), std::end(nodes)); return nodes; } @@ -76,27 +76,24 @@ std::set
ConnectionManager::GetNonRoutingNodes() const { return connected_non_routing_nodes_; } -//boost::optional ConnectionManager::LostNetworkConnection( +// boost::optional ConnectionManager::LostNetworkConnection( // const Address& node) { // routing_table_.DropNode(node); // return GroupChanged(); // } -//optional ConnectionManager::DropNode(const Address& their_id) { +// optional ConnectionManager::DropNode(const Address& their_id) { // routing_table_.DropNode(their_id); // // FIXME(Prakash) remove connection ? // return GroupChanged(); //} -void ConnectionManager::DropNode(const Address& their_id) { - connections_->Drop(their_id); -} +void ConnectionManager::DropNode(const Address& their_id) { connections_->Drop(their_id); } void ConnectionManager::StartAccepting() { std::weak_ptr weak_connections = connections_; - connections_->Accept( our_accept_port_ - , &our_accept_port_ - , [=](asio::error_code error, Connections::AcceptResult result) { + connections_->Accept(our_accept_port_, &our_accept_port_, [=](asio::error_code error, + Connections::AcceptResult result) { if (!weak_connections.lock()) { return; } @@ -107,16 +104,13 @@ void ConnectionManager::StartAccepting() { auto expected = std::move(expected_i->second); expected_accepts_.erase(expected_i); - HandleAddNode( error - , std::move(expected.node_info) - , std::move(expected.handler)); + HandleAddNode(error, std::move(expected.node_info), std::move(expected.handler)); // The handler may have destroyed 'this'. if (!weak_connections.lock()) { return; } - } - else { + } else { if (!error) { connected_non_routing_nodes_.insert(result.his_address); } @@ -130,10 +124,8 @@ void ConnectionManager::StartAccepting() { LOG(kInfo) << "StartAccepting() port " << our_accept_port_; } -void ConnectionManager::HandleAddNode( asio::error_code error - , NodeInfo node_info - , OnAddNode user_handler) -{ +void ConnectionManager::HandleAddNode(asio::error_code error, NodeInfo node_info, + OnAddNode user_handler) { if (error && error != asio::error::timed_out) { return; } @@ -143,57 +135,50 @@ void ConnectionManager::HandleAddNode( asio::error_code error user_handler(error, AddToRoutingTable(std::move(node_info))); } -void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, - OnAddNode on_node_added) { +void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, OnAddNode on_node_added) { auto id = node_info.id; auto timer = std::make_shared(io_service_); - auto canceling_handler = [on_node_added, timer]( asio::error_code error - , boost::optional diff) { - timer->cancel(); - on_node_added(error, std::move(diff)); - }; + auto canceling_handler = + [on_node_added, timer](asio::error_code error, boost::optional diff) { + timer->cancel(); + on_node_added(error, std::move(diff)); + }; - auto insert_result = expected_accepts_.insert - (std::make_pair(id, - ExpectedAccept{node_info, - canceling_handler})); + auto insert_result = + expected_accepts_.insert(std::make_pair(id, ExpectedAccept{node_info, canceling_handler})); if (!insert_result.second) { - return io_service_.post([on_node_added]() { - on_node_added(asio::error::already_started, boost::none); - }); + return io_service_.post( + [on_node_added]() { on_node_added(asio::error::already_started, boost::none); }); } // TODO(Team): Is the timeout value correct? Should it be in defined // somewhere else? timer->async_wait(std::chrono::seconds(10), [=]() { - expected_accepts_.erase(id); - HandleAddNode(asio::error::timed_out, node_info, on_node_added); - }); + expected_accepts_.erase(id); + HandleAddNode(asio::error::timed_out, node_info, on_node_added); + }); } -void ConnectionManager::AddNode( NodeInfo node_to_add - , EndpointPair their_endpoint_pair - , OnAddNode on_node_added) { - +void ConnectionManager::AddNode(NodeInfo node_to_add, EndpointPair their_endpoint_pair, + OnAddNode on_node_added) { std::weak_ptr weak_connections = connections_; // TODO(PeterJ): Use local endpoint as well - connections_->Connect( their_endpoint_pair.external - , [=]( asio::error_code error - , Connections::ConnectResult result) { - if (!weak_connections.lock()) { - return on_node_added(asio::error::operation_aborted, boost::none); - } - - if (!error && (result.his_address != node_to_add.id)) { - error = asio::error::fault; - } - - HandleAddNode(error, node_to_add, on_node_added); - }); + connections_->Connect(their_endpoint_pair.external, + [=](asio::error_code error, Connections::ConnectResult result) { + if (!weak_connections.lock()) { + return on_node_added(asio::error::operation_aborted, boost::none); + } + + if (!error && (result.his_address != node_to_add.id)) { + error = asio::error::fault; + } + + HandleAddNode(error, node_to_add, on_node_added); + }); } boost::optional ConnectionManager::AddToRoutingTable(NodeInfo node_to_add) { @@ -235,14 +220,16 @@ void ConnectionManager::StartReceiving() { std::weak_ptr weak_connections = connections_; connections_->Receive([=](asio::error_code error, Connections::ReceiveResult result) { - if (!weak_connections.lock()) return; + if (!weak_connections.lock()) + return; if (error) { return HandleConnectionLost(result.his_address); } auto h = std::move(on_receive_); if (h) { h(std::move(result.his_address), std::move(result.message)); - if (!weak_connections.lock()) return; + if (!weak_connections.lock()) + return; on_receive_ = std::move(h); } StartReceiving(); @@ -251,8 +238,8 @@ void ConnectionManager::StartReceiving() { void ConnectionManager::SendToNonRoutingNode(const Address& /*addr*/, const SerialisedMessage& /*message*/) { -// connections_->Send(addr, message, std::move(handler)); -// remove connection if failed + // connections_->Send(addr, message, std::move(handler)); + // remove connection if failed } diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index f7a76d00..d5364bb2 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -64,8 +64,8 @@ class ConnectionManager { using PublicPmid = passport::PublicPmid; public: - using OnReceive = std::function; - using OnAddNode = std::function)>; + using OnReceive = std::function; + using OnAddNode = std::function)>; using OnConnectionLost = std::function, Address)>; private: @@ -75,7 +75,8 @@ class ConnectionManager { }; public: - ConnectionManager(asio::io_service& ios, Address our_id, OnReceive on_receive, OnConnectionLost on_connection_lost); + ConnectionManager(asio::io_service& ios, Address our_id, OnReceive on_receive, + OnConnectionLost on_connection_lost); ConnectionManager(const ConnectionManager&) = delete; ConnectionManager(ConnectionManager&&) = delete; @@ -90,7 +91,7 @@ class ConnectionManager { boost::optional LostNetworkConnection(const Address& node); // routing wishes to drop a specific node (may be a node we cannot connect to) - //boost::optional DropNode(const Address& their_id); + // boost::optional DropNode(const Address& their_id); void DropNode(const Address& their_id); void AddNode(NodeInfo node_to_add, EndpointPair their_endpoint_pair, OnAddNode); @@ -123,7 +124,8 @@ class ConnectionManager { template void Send(const Address&, const SerialisedMessage&, Handler); - void SendToNonRoutingNode(const Address&, const SerialisedMessage&); // remove connection if fails + void SendToNonRoutingNode(const Address&, + const SerialisedMessage&); // remove connection if fails unsigned short AcceptingPort() const { return our_accept_port_; } @@ -143,7 +145,6 @@ class ConnectionManager { boost::optional GroupChanged(); private: - asio::io_service& io_service_; mutable std::mutex mutex_; unsigned short our_accept_port_; @@ -162,22 +163,23 @@ void ConnectionManager::Send(const Address& addr, const SerialisedMessage& messa std::weak_ptr guard = connections_; LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); connections_->Send(addr, message, [=](asio::error_code error) { - handler(error); + handler(error); - if (!guard.lock()) return; + if (!guard.lock()) + return; - if (error) { - HandleConnectionLost(std::move(addr)); - } - }); + if (error) { + HandleConnectionLost(std::move(addr)); + } + }); } template void ConnectionManager::Connect(asio::ip::udp::endpoint remote_endpoint, Handler handler) { - connections_->Connect(remote_endpoint, [=](asio::error_code error, - Connections::ConnectResult result) { - handler(error, result.his_address, result.our_endpoint); - }); + connections_->Connect(remote_endpoint, + [=](asio::error_code error, Connections::ConnectResult result) { + handler(error, result.his_address, result.our_endpoint); + }); } } // namespace routing diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index e6038464..69630114 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -43,21 +43,21 @@ namespace routing { class Connections { public: - struct AcceptResult { - Endpoint his_endpoint; - Address his_address; - Endpoint our_endpoint; // As seen by the other end - }; - - struct ConnectResult { - Address his_address; - Endpoint our_endpoint; // As seen by the other end - }; - - struct ReceiveResult { - Address his_address; - SerialisedMessage message; - }; + struct AcceptResult { + Endpoint his_endpoint; + Address his_address; + Endpoint our_endpoint; // As seen by the other end + }; + + struct ConnectResult { + Address his_address; + Endpoint our_endpoint; // As seen by the other end + }; + + struct ReceiveResult { + Address his_address; + SerialisedMessage message; + }; public: Connections(asio::io_service&, const Address& our_node_id); @@ -82,8 +82,8 @@ class Connections { // The secont argument is an ugly C-style return of the actual port that has been // chosen. TODO: Try to return it using a proper C++ way. template - AsyncResultReturn - Accept(unsigned short port, unsigned short* chosen_port, Token&&); + AsyncResultReturn Accept(unsigned short port, unsigned short* chosen_port, + Token&&); void Drop(const Address& their_id); @@ -101,7 +101,7 @@ class Connections { void StartReceiving(const Address&, const crux::endpoint&, const std::shared_ptr&); void OnReceive(asio::error_code, ReceiveResult); - template + template void post(Handler&& handler, Args&&... args); private: @@ -120,7 +120,7 @@ class Connections { struct ReceiveInput { asio::error_code error; - ReceiveResult result; + ReceiveResult result; }; using ReceiveOutput = std::function; @@ -132,11 +132,7 @@ class Connections { }; inline Connections::Connections(asio::io_service& ios, const Address& our_node_id) - : service(ios), - work_(new asio::io_service::work(ios)), - our_id_(our_node_id), - runner_(1) -{} + : service(ios), work_(new asio::io_service::work(ios)), our_id_(our_node_id), runner_(1) {} template AsyncResultReturn Connections::Send(const Address& remote_id, const SerialisedMessage& bytes, @@ -149,7 +145,7 @@ AsyncResultReturn Connections::Send(const Address& remote_id, const Seria auto remote_endpoint_i = id_to_endpoint_map_.find(remote_id); if (remote_endpoint_i == id_to_endpoint_map_.end()) { - LOG(kWarning) << "bad_descriptor !! " << remote_id; + LOG(kWarning) << "bad_descriptor !! " << remote_id; return post(handler, asio::error::bad_descriptor); } @@ -185,15 +181,14 @@ AsyncResultReturn Connections::Receive(Token& asio::async_result result(handler); get_io_service().post([=]() mutable { - if (!receive_input_.empty()) { - auto input = std::move(receive_input_.front()); - receive_input_.pop(); - post(handler, input.error, std::move(input.result)); - } - else { - receive_output_.push(std::move(handler)); - } - }); + if (!receive_input_.empty()) { + auto input = std::move(receive_input_.front()); + receive_input_.pop(); + post(handler, input.error, std::move(input.result)); + } else { + receive_output_.push(std::move(handler)); + } + }); return result.get(); } @@ -203,8 +198,7 @@ inline void Connections::OnReceive(asio::error_code error, ReceiveResult result) auto handler = std::move(receive_output_.front()); receive_output_.pop(); post(handler, error, std::move(result)); - } - else { + } else { receive_input_.push(ReceiveInput{error, std::move(result)}); } } @@ -217,7 +211,6 @@ inline Connections::~Connections() { template AsyncResultReturn Connections::Connect(Endpoint endpoint, Token&& token) { - using Handler = AsyncResultHandler; Handler handler(std::forward(token)); asio::async_result result(handler); @@ -278,25 +271,23 @@ AsyncResultReturn Connections::Connect(Endpoi } template -AsyncResultReturn -Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& token) { - +AsyncResultReturn Connections::Accept(unsigned short port, + unsigned short* chosen_port, + Token&& token) { using Handler = AsyncResultHandler; Handler handler(std::forward(token)); asio::async_result result(handler); - auto loopback = [](unsigned short port) { - return crux::endpoint(boost::asio::ip::udp::v4(), port); - }; + auto loopback = + [](unsigned short port) { return crux::endpoint(boost::asio::ip::udp::v4(), port); }; // TODO(PeterJ):Make sure this operation is thread safe in crux. std::shared_ptr acceptor; try { acceptor = std::make_shared(get_io_service(), loopback(port)); - } - catch(...) { + } catch (...) { acceptor = std::make_shared(get_io_service(), loopback(0)); } @@ -308,8 +299,7 @@ Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& to auto find_result = acceptors_.insert(std::make_pair(port, acceptor)); if (!find_result.second /* inserted? */) { - return post(handler,asio::error::already_started, Connections::AcceptResult()); - + return post(handler, asio::error::already_started, Connections::AcceptResult()); } std::weak_ptr weak_acceptor = acceptor; @@ -318,11 +308,11 @@ Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& to acceptor->async_accept(*socket, [=](boost::system::error_code error) mutable { if (!weak_acceptor.lock()) { - return post(handler,asio::error::operation_aborted, AcceptResult()); + return post(handler, asio::error::operation_aborted, AcceptResult()); } if (error) { - return post(handler,asio::error::operation_aborted, AcceptResult()); + return post(handler, asio::error::operation_aborted, AcceptResult()); } acceptors_.erase(port); @@ -337,14 +327,14 @@ Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& to auto socket = weak_socket.lock(); if (!socket) { - return post(handler,asio::error::operation_aborted, - AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); - } + return post(handler, asio::error::operation_aborted, + AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); + } if (error) { connections_.erase(remote_endpoint); - return post(handler,convert::ToStd(error), - AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); + return post(handler, convert::ToStd(error), + AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); } InputVectorStream stream(data); @@ -355,8 +345,8 @@ Connections::Accept(unsigned short port, unsigned short* chosen_port, Token&& to id_to_endpoint_map_[his_id] = remote_endpoint; StartReceiving(his_id, remote_endpoint, socket); - post(handler,convert::ToStd(error), - AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); + post(handler, convert::ToStd(error), + AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); }); }); }); @@ -405,16 +395,12 @@ inline void Connections::Shutdown() { }); } -inline void Connections::Wait() { - runner_.Stop(); -} +inline void Connections::Wait() { runner_.Stop(); } -template +template void Connections::post(Handler&& handler, Args&&... args) { std::tuple::type...> tuple(std::forward(args)...); - service.post([handler, tuple]() mutable { - ApplyTuple(handler, tuple); - }); + service.post([handler, tuple]() mutable { ApplyTuple(handler, tuple); }); } inline void Connections::Drop(const Address& their_id) { diff --git a/src/maidsafe/routing/timer.h b/src/maidsafe/routing/timer.h index d3eea092..032010b3 100644 --- a/src/maidsafe/routing/timer.h +++ b/src/maidsafe/routing/timer.h @@ -19,43 +19,36 @@ #ifndef MAIDSAFE_ROUTING_TIMER_H_ #define MAIDSAFE_ROUTING_TIMER_H_ -#include #include +#include + #include "asio/steady_timer.hpp" -namespace maidsafe -{ +namespace maidsafe { -namespace routing -{ +namespace routing { class Timer { - enum State { idle, running, canceled }; - public: Timer(asio::io_service&); ~Timer(); - template + template void async_wait(asio::steady_timer::duration, Handler&&); void cancel(); private: + enum State { idle, running, canceled }; asio::steady_timer timer_; std::shared_ptr state_; }; -inline Timer::Timer(asio::io_service& ios) - : timer_(ios), - state_(std::make_shared(idle)) -{} +inline Timer::Timer(asio::io_service& ios) : timer_(ios), state_(std::make_shared(idle)) {} -inline Timer::~Timer() { - cancel(); -} +inline Timer::~Timer() { cancel(); } -template +template void Timer::async_wait(asio::steady_timer::duration duration, Handler&& handler) { auto state = state_; assert(*state == idle && "Current implementation allows only one async_wait invocation"); @@ -63,11 +56,11 @@ void Timer::async_wait(asio::steady_timer::duration duration, Handler&& handler) timer_.expires_from_now(duration); // FIXME(Team): forward the handler if we're using c++14 timer_.async_wait([state, handler](const asio::error_code&) { - if (*state != running) { - return; - } - handler(); - }); + if (*state != running) { + return; + } + handler(); + }); } inline void Timer::cancel() { @@ -75,9 +68,8 @@ inline void Timer::cancel() { timer_.cancel(); } -} // routing namespace - -} // maidsafe namespace +} // routing namespace -#endif // MAIDSAFE_ROUTING_TIMER_H_ +} // maidsafe namespace +#endif // MAIDSAFE_ROUTING_TIMER_H_ From 80bc1a24a4d2841bc2f82b580ebd3f47499ce4ce Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Fri, 20 Mar 2015 17:28:50 +0000 Subject: [PATCH 53/72] Changed to use shared_ptr to base data type. --- include/maidsafe/routing/routing_node.h | 74 +++++++++++-------- src/maidsafe/routing/connection_manager.h | 4 +- .../tests/routing_fake_vault_facade_test.cc | 23 ++++-- .../routing/tests/utils/fake_vault_facade.cc | 11 ++- .../routing/tests/utils/fake_vault_facade.h | 4 - 5 files changed, 70 insertions(+), 46 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 68ff5db2..22879dcf 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -74,13 +74,13 @@ class RoutingNode { // // will return with the data template - GetReturn Get(Data::NameAndTypeId name_and_type_id, CompletionToken token); + GetReturn Get(Data::NameAndTypeId name_and_type_id, CompletionToken&& token); // will return with allowed or not (error_code only) - template - PutReturn Put(DataType data, CompletionToken token); + template + PutReturn Put(std::shared_ptr data, CompletionToken&& token); // will return with allowed or not (error_code only) template - PostReturn Post(Address to, FunctorType functor, CompletionToken token); + PostReturn Post(Address to, FunctorType functor, CompletionToken&& token); void AddBootstrapContact(Contact bootstrap_contact) { bootstrap_handler_.AddBootstrapContacts(std::vector(1, bootstrap_contact)); @@ -154,7 +154,7 @@ class RoutingNode { ConnectionManager connection_manager_; LruCache filter_; Sentinel sentinel_; - LruCache cache_; + LruCache cache_; std::shared_ptr destroy_indicator_; }; @@ -179,7 +179,8 @@ RoutingNode::RoutingNode() LOG(kInfo) << "RoutingNode < " << OurId() << " >"; // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. - cache_.Add(our_fob_.name(), Serialise(passport::PublicPmid(our_fob_))); + passport::PublicPmid our_public_pmid(our_fob_); + cache_.Add(our_public_pmid.NameAndType(), Serialise(our_public_pmid)); StartBootstrap(); } @@ -213,13 +214,13 @@ void RoutingNode::StartBootstrap() { template void RoutingNode::PutOurPublicPmid() { assert(bootstrap_node_); - passport::PublicPmid our_public_pmid{passport::PublicPmid(our_fob_)}; - auto name = our_public_pmid.Name(); - auto type_id = our_public_pmid.TypeId(); + std::shared_ptr our_public_pmid{new passport::PublicPmid(our_fob_)}; + auto name = our_public_pmid->Name(); + auto type_id = our_public_pmid->TypeId(); asio::post(asio_service_.service(), [=] { // FIXME(Prakash) request should be signed and may be sent to ClientManager PutData put_data_message(type_id, Serialise(our_public_pmid)); - SendToBootstrapNode(std::make_pair(Destination(Address(name)), boost::none), OurSourceAddress(), + SendToBootstrapNode(std::make_pair(Destination(name), boost::none), OurSourceAddress(), put_data_message, Authority::client); }); } @@ -227,7 +228,7 @@ void RoutingNode::PutOurPublicPmid() { template template GetReturn RoutingNode::Get(Data::NameAndTypeId name_and_type_id, - CompletionToken token) { + CompletionToken&& token) { GetHandler handler(std::forward(token)); asio::async_result result(handler); asio::post(asio_service_.service(), [=] { @@ -241,26 +242,35 @@ GetReturn RoutingNode::Get(Data::NameAndTypeId name_and_ }); return result.get(); } + // As this is a routing_node this should be renamed to PutPublicPmid one time // and possibly it should be a single type it deals with rather than Put as this call is // special // amongst all node types and is the only unauthorised Put anywhere // nodes have no reason to Put anywhere else template -template -PutReturn RoutingNode::Put(DataType data, CompletionToken token) { +template +PutReturn RoutingNode::Put(std::shared_ptr data, + CompletionToken&& token) { PutHandler handler(std::forward(token)); asio::async_result result(handler); - asio::post(asio_service_.service(), [=] { + asio::post(asio_service_.service(), [=]() mutable { MessageHeader our_header( std::make_pair(Destination(OurId()), boost::none), // send to ClientMgr OurSourceAddress(), ++message_id_, Authority::client); - PutData request(data.TypeId(), Serialise(data)); + PutData request(data->TypeId(), Serialise(data)); // FIXME(dirvine) For client in real put this needs signed :08/02/2015 auto message(Serialise(our_header, MessageToTag::value(), request)); - for (const auto& target : connection_manager_.GetTarget(OurId())) + auto targets(connection_manager_.GetTarget(OurId())); + for (const auto& target : targets) { connection_manager_.Send(target.id, message, [](asio::error_code) {}); - connection_manager_.Send(*bootstrap_node_, message, [](asio::error_code) {}); + } + if (targets.empty() && bootstrap_node_) { + connection_manager_.Send(*bootstrap_node_, message, + [handler](std::error_code ec) mutable { handler(ec); }); + } else { + handler(make_error_code(RoutingErrors::not_connected)); + } }); return result.get(); } @@ -268,7 +278,7 @@ PutReturn RoutingNode::Put(DataType data, CompletionToke template template PostReturn RoutingNode::Post(Address to, FunctorType functor, - CompletionToken token) { + CompletionToken&& token) { PostHandler handler(std::forward(token)); asio::async_result result(handler); asio::post(asio_service_.service(), [=] { @@ -281,6 +291,7 @@ PostReturn RoutingNode::Post(Address to, FunctorType fun for (const auto& target : connection_manager_.GetTarget(to)) { connection_manager_.Send(target.id, message, [](asio::error_code) {}); } + handler(); }); return result.get(); } @@ -325,13 +336,15 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri // We add these to cache if (tag == MessageTypeTag::GetDataResponse) { auto data = Parse(binary_input_stream); - if (data.data()) - cache_.Add(data.name_and_type_id().name, *data.data()); + if (data.data()) { + std::shared_ptr parsed(Parse>(*data.data())); + cache_.Add(parsed->NameAndType(), *data.data()); + } } // if we can satisfy request from cache we do if (tag == MessageTypeTag::GetData) { auto data = Parse(binary_input_stream); - auto test = cache_.Get(data.name_and_type_id().name); + auto test = cache_.Get(data.name_and_type_id()); // FIXME(dirvine) move to upper lauer :09/02/2015 // if (test) { // GetDataResponse response(data.name(), test); @@ -613,14 +626,17 @@ void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { } template -void RoutingNode::HandleMessage(PutData put_data, MessageHeader /*original_header*/) { - // FIXME(Prakash) - // cache_.Add(put_data.name_and_type_id().name, *put_data.data()); - LOG(kVerbose) << "Put Data : " << put_data.type_id(); - // auto result = static_cast(this)->HandlePut( - // original_header.Source(), original_header.FromAuthority(), - // OurAuthority(put_data.name_and_type_id().name, original_header), - // put_data.name_and_type_id(), put_data.data()); +void RoutingNode::HandleMessage(PutData put_data, MessageHeader original_header) { + LOG(kVerbose) << "Handling PutData: " << put_data.type_id() << " " + << hex::Substr(put_data.data()) << " " << put_data.data().size(); + std::shared_ptr parsed(Parse>(put_data.data())); + cache_.Add(parsed->NameAndType(), put_data.data()); + auto result = static_cast(this) + ->HandlePut(original_header.Source(), original_header.FromAuthority(), + OurAuthority(parsed->NameAndType().name, original_header), parsed); + if (result) { + // TODO(Fraser#5#): 2015-03-20 - Return error somehow. + } } template diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index d5364bb2..b41c91b8 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -162,8 +162,8 @@ void ConnectionManager::Send(const Address& addr, const SerialisedMessage& messa Handler handler) { std::weak_ptr guard = connections_; LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); - connections_->Send(addr, message, [=](asio::error_code error) { - handler(error); + connections_->Send(addr, message, [=](asio::error_code error) mutable { + handler(error); if (!guard.lock()) return; diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index ca67bd65..3c3acdeb 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -32,24 +32,31 @@ namespace test { TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { vault::test::FakeVaultFacade vault1; - Sleep(std::chrono::seconds(1)); vault::test::FakeVaultFacade vault2; - //ASSERT_NO_THROW(vault::test::FakeVaultFacade vault); Sleep(std::chrono::seconds(5)); LOG(kInfo) << "================================================================================="; + std::shared_ptr immutable_data(new ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50)))); + std::future put_future( + vault2.Put(immutable_data, asio::use_future)); + EXPECT_NO_THROW(put_future.get()); + passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); + std::shared_ptr public_maid(new passport::PublicMaid(maid_and_signer.first)); + put_future = vault1.Put(public_maid, asio::use_future); + EXPECT_NO_THROW(put_future.get()); + + AsioService asio_service(1); asio::spawn(asio_service.service(), [&](asio::yield_context yield) { std::error_code error; - vault2.Put(ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50))), yield[error]); - EXPECT_FALSE(error); - passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); - vault1.Put(passport::PublicMaid(maid_and_signer.first), yield[error]); - EXPECT_FALSE(error); + vault2.Put(immutable_data, yield[error]); + EXPECT_FALSE(error) << error.message(); + vault1.Put(public_maid, yield[error]); + EXPECT_FALSE(error) << error.message(); }); - Sleep(std::chrono::seconds(1)); + Sleep(std::chrono::seconds(5)); asio_service.Stop(); } diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index 909c048d..e11bc7cf 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -38,9 +38,14 @@ namespace test { // ImmutableData::serialised_type(NonEmptyString(content))); //} -routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress /*from*/, - routing::Authority /*from_authority*/, routing::Authority /*authority*/, - Data::NameAndTypeId /*name_and_type_id*/, SerialisedData /*serialised_data*/) { +routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, + routing::Authority from_authority, + routing::Authority our_authority, + std::shared_ptr data) { + LOG(kVerbose) << "Received Put request from " << from.node_address.data << " with Data name " + << data->Name() << " and type " << static_cast(data->TypeId()); + (void)from_authority; + (void)our_authority; // switch (authority) { // case routing::Authority::client_manager: // if (from_authority != routing::Authority::client) diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index e5fa82d5..7517c184 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -111,13 +111,9 @@ class FakeVaultFacade : public MaidManager, routing::Authority authority, Data::NameAndTypeId name_and_type_id); - routing::HandlePutPostReturn HandlePut(routing::SourceAddress from, - routing::Authority from_authority, routing::Authority authority, - Data::NameAndTypeId name_and_type_id, SerialisedData serialised_data); routing::HandlePutPostReturn HandlePut(routing::SourceAddress from, routing::Authority from_authority, - routing::Destination to, routing::Authority our_authority, std::shared_ptr data); From 77a40df04ee3c4617c4ed71187c3cf295f758f4c Mon Sep 17 00:00:00 2001 From: prakash Date: Fri, 20 Mar 2015 17:41:27 +0000 Subject: [PATCH 54/72] wip on relay --- include/maidsafe/routing/routing_node.h | 18 +++++++++++------- src/maidsafe/routing/message_header.h | 4 +++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 25088bf6..609edad8 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -373,10 +373,14 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri // Drop message before Sentinel check if it is a direct message type (Connect, ConnectResponse) // and this node is in the group but the message destination is another group member node. + // TODO(Prakash) cleanup aim to abstract relay logic here and may be use term routed message for + // response messages if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { - if (header.Destination().first.data != connection_manager_.OurId()) { // not for me - LOG(kVerbose) << "not for me"; - return; + if (header.Destination().first.data != OurId()) { // not for me + if ((header.Destination().second) && (*header.Destination().second).data != OurId()) { + LOG(kVerbose) << "not for me"; + return; + } } } @@ -496,7 +500,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h //////////////////////// std::weak_ptr destroy_guard = destroy_indicator_; - + LOG(kError) << " AddNodeAccept "; connection_manager_.AddNodeAccept (NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints(), @@ -517,13 +521,13 @@ LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " << c // Workaround because ConnectResponse isn't copyconstructibe. auto response_ptr = std::make_shared(std::move(connect_response)); - + LOG(kError) << " AddNode "; connection_manager_.AddNode( NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), response_ptr->receiver_endpoints(), [=](boost::optional added, Endpoint /* our_endpoint */) { - if (!destroy_guard.lock()) return; - + if (!destroy_guard.lock()) + return; auto target = response_ptr->requester_id(); if (added) static_cast(this)->HandleChurn(*added); diff --git a/src/maidsafe/routing/message_header.h b/src/maidsafe/routing/message_header.h index 5b03f663..7f3ab908 100644 --- a/src/maidsafe/routing/message_header.h +++ b/src/maidsafe/routing/message_header.h @@ -117,7 +117,9 @@ class MessageHeader { NodeAddress FromNode() const { return source_.node_address; } boost::optional FromGroup() const { return source_.group_address; } Authority FromAuthority() { return authority_; } - bool RelayedMessage() const { return static_cast(source_.reply_to_address); } + bool RelayedMessage() const { + return (static_cast(source_.reply_to_address) || + static_cast(destination_.second)); } boost::optional ReplyToAddress() const { return source_.reply_to_address; } From 98162196fe881f45f123f535f593c9188f8cca7d Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 23 Mar 2015 02:14:47 +0000 Subject: [PATCH 55/72] minor fix --- include/maidsafe/routing/routing_node.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index a1bb20b7..e751c07a 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -529,7 +529,7 @@ template void RoutingNode::HandleMessage(ConnectResponse connect_response) { LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " << connect_response.receiver_id(); - if (!connection_manager_.SuggestNodeToAdd(connect_response.requester_id())) + if (!connection_manager_.SuggestNodeToAdd(connect_response.receiver_id())) return; std::weak_ptr destroy_guard = destroy_indicator_; From cb03a28666aabe25fddb4ce53a7b104a56ec8165 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Mon, 23 Mar 2015 16:49:41 +0000 Subject: [PATCH 56/72] Bugfix for IPv4/v6 handling in Connections. --- include/maidsafe/routing/routing_node.h | 4 ++-- src/maidsafe/routing/connections.h | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index e751c07a..e1c6b440 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -72,7 +72,7 @@ class RoutingNode { template BootstrapReturn Bootstrap(Endpoint endpoint, CompletionToken&& token); - // // will return with the data + // will return with the data template GetReturn Get(Data::NameAndTypeId name_and_type_id, CompletionToken&& token); // will return with allowed or not (error_code only) @@ -503,7 +503,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h auto temp = (*original_header.ReplyToAddress()).data; auto message = Serialise(header, MessageToTag::value(), respond); - connection_manager_.Send(temp, message, [=](asio::error_code error) { + connection_manager_.Send(temp, std::move(message), [=](asio::error_code error) { if (error) { LOG(kWarning) << "Could not send to " << temp; } else { diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 69630114..a63d613b 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -216,7 +216,12 @@ AsyncResultReturn Connections::Connect(Endpoi asio::async_result result(handler); get_io_service().post([=]() mutable { - crux::endpoint unspecified_ep(boost::asio::ip::udp::v4(), 0); + crux::endpoint unspecified_ep; + if (endpoint.address().is_v4()) + unspecified_ep = crux::endpoint(boost::asio::ip::udp::v4(), 0); + else + unspecified_ep = crux::endpoint(boost::asio::ip::udp::v6(), 0); + auto socket = std::make_shared(get_io_service(), unspecified_ep); auto insert_result = connections_.insert(std::make_pair(convert::ToBoost(endpoint), socket)); From 122f4dd7c169b5cd8438a22df39a7fd15ff4c2d1 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Mon, 23 Mar 2015 16:57:47 +0000 Subject: [PATCH 57/72] Missed file in merge. --- include/maidsafe/routing/types.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/maidsafe/routing/types.h b/include/maidsafe/routing/types.h index 29a944b4..7954bfca 100644 --- a/include/maidsafe/routing/types.h +++ b/include/maidsafe/routing/types.h @@ -88,6 +88,9 @@ using HandleGetReturn = boost::expected, std::vector>, maidsafe_error>; using HandlePutPostReturn = boost::expected, maidsafe_error>; +using HandlePostReturn = + boost::expected, std::vector>, + maidsafe_error>; using Endpoint = asio::ip::udp::endpoint; using Port = uint16_t; From 9fb6d3c625caca90030fa8511d26db8cc2aaf639 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Mon, 23 Mar 2015 17:20:58 +0000 Subject: [PATCH 58/72] Renamed HandlePutPostReturn to HandlePutReturn. --- include/maidsafe/routing/types.h | 9 +- .../tests/routing_vault_network_test.cc | 25 +++--- .../routing/tests/utils/fake_vault_facade.cc | 82 +++++++++---------- .../routing/tests/utils/fake_vault_facade.h | 52 ++++++------ 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/include/maidsafe/routing/types.h b/include/maidsafe/routing/types.h index 7954bfca..2a34a883 100644 --- a/include/maidsafe/routing/types.h +++ b/include/maidsafe/routing/types.h @@ -87,10 +87,9 @@ using FilterType = std::pair; using HandleGetReturn = boost::expected, std::vector>, maidsafe_error>; -using HandlePutPostReturn = boost::expected, maidsafe_error>; +using HandlePutReturn = boost::expected, maidsafe_error>; using HandlePostReturn = - boost::expected, std::vector>, - maidsafe_error>; + boost::expected, std::vector>, maidsafe_error>; using Endpoint = asio::ip::udp::endpoint; using Port = uint16_t; @@ -99,8 +98,8 @@ using CloseGroupDifference = std::pair, std::vector
; template -using AsyncResultHandler = - typename asio::handler_type::type, void(asio::error_code, Args...)>::type; +using AsyncResultHandler = typename asio::handler_type::type, + void(asio::error_code, Args...)>::type; template using AsyncResultReturn = diff --git a/src/maidsafe/routing/tests/routing_vault_network_test.cc b/src/maidsafe/routing/tests/routing_vault_network_test.cc index 4a148d3e..ca3720a1 100644 --- a/src/maidsafe/routing/tests/routing_vault_network_test.cc +++ b/src/maidsafe/routing/tests/routing_vault_network_test.cc @@ -116,7 +116,7 @@ class MaidManager { public: using account_type = MaidManagerAccount; template - HandlePutPostReturn HandlePut(SourceAddress from, Identity data_name, T data) { + HandlePutReturn HandlePut(SourceAddress from, Identity data_name, T data) { auto found = static_cast(this)->maid_account(from.node_address); if (!found) return boost::make_unexpected(MakeError(VaultErrors::no_such_account)); @@ -270,8 +270,7 @@ class VaultFacade : public test::MaidManager, bool HandlePut(Address, SerialisedMessage) { return true; } // if the implementation allows any put of data in unauthenticated mode bool HandleUnauthenticatedPut(Address, SerialisedMessage) { return true; } - void HandleConnectionAdded(Address) { - } + void HandleConnectionAdded(Address) {} void HandleChurn(CloseGroupDifference diff) { MaidManager::HandleChurn(diff); @@ -291,20 +290,20 @@ TEST(VaultNetworkTest, FUNC_CreateNetPutGetData) { // other async actions (same with the tests below). -// LruCache cache(0, std::chrono::seconds(0)); + // LruCache cache(0, std::chrono::seconds(0)); -// RoutingNode n; + // RoutingNode n; -// NonEmptyString value(RandomAlphaNumericBytes(65)); -// Identity name(crypto::Hash(value)); -// MutableData a(name, value); -// ImmutableData b(value); + // NonEmptyString value(RandomAlphaNumericBytes(65)); + // Identity name(crypto::Hash(value)); + // MutableData a(name, value); + // ImmutableData b(value); -// Address from(MakeIdentity()); -// Address to(MakeIdentity()); + // Address from(MakeIdentity()); + // Address to(MakeIdentity()); -// n.Get(b.NameAndType(), [](asio::error_code /* error */) {}); -// n.Get(a.NameAndType(), [](asio::error_code /* error */) {}); + // n.Get(b.NameAndType(), [](asio::error_code /* error */) {}); + // n.Get(a.NameAndType(), [](asio::error_code /* error */) {}); // n.Put(to, b, [](asio::error_code /* error */) {}); // n.Put(to, a, [](asio::error_code /* error */) {}); diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index e11bc7cf..b6f9323b 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -29,8 +29,8 @@ namespace vault { namespace test { -//template <> -//ImmutableData ParseData(const SerialisedData& serialised_data) { +// template <> +// ImmutableData ParseData(const SerialisedData& serialised_data) { // auto digest_size(crypto::SHA512::DIGESTSIZE); // std::string name(serialised_data.begin(), serialised_data.begin() + digest_size); // std::string content(serialised_data.begin() + digest_size, serialised_data.end()); @@ -38,56 +38,56 @@ namespace test { // ImmutableData::serialised_type(NonEmptyString(content))); //} -routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, - routing::Authority from_authority, - routing::Authority our_authority, - std::shared_ptr data) { +routing::HandlePutReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, + routing::Authority from_authority, + routing::Authority our_authority, + std::shared_ptr data) { LOG(kVerbose) << "Received Put request from " << from.node_address.data << " with Data name " << data->Name() << " and type " << static_cast(data->TypeId()); (void)from_authority; (void)our_authority; -// switch (authority) { -// case routing::Authority::client_manager: -// if (from_authority != routing::Authority::client) -// break; -// if (name_and_type_id.type_id == detail::TypeId::value) -// return MaidManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return MaidManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return MaidManager::HandlePut(from, Parse(serialised_data)); -// case routing::Authority::nae_manager: -// if (from_authority != routing::Authority::client_manager) -// break; -// if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::HandlePut(from, Parse(serialised_data)); -// break; -// default: -// break; -// } + // switch (authority) { + // case routing::Authority::client_manager: + // if (from_authority != routing::Authority::client) + // break; + // if (name_and_type_id.type_id == detail::TypeId::value) + // return MaidManager::HandlePut(from, Parse(serialised_data)); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return MaidManager::HandlePut(from, Parse(serialised_data)); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return MaidManager::HandlePut(from, Parse(serialised_data)); + // case routing::Authority::nae_manager: + // if (from_authority != routing::Authority::client_manager) + // break; + // if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::HandlePut(from, Parse(serialised_data)); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::HandlePut(from, Parse(serialised_data)); + // break; + // default: + // break; + // } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } routing::HandleGetReturn FakeVaultFacade::HandleGet(routing::SourceAddress /*from*/, - routing::Authority /*from_authority*/, routing::Authority /*authority*/, - Data::NameAndTypeId /*name_and_type_id*/) { -// switch (authority) { -// case routing::Authority::nae_manager: -// if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::template HandleGet(from, data_name); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::template HandleGet(from, data_name); -// break; -// default: -// break; -// } + routing::Authority /*from_authority*/, + routing::Authority /*authority*/, + Data::NameAndTypeId /*name_and_type_id*/) { + // switch (authority) { + // case routing::Authority::nae_manager: + // if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::template HandleGet(from, data_name); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::template HandleGet(from, data_name); + // break; + // default: + // break; + // } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } -void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) { -} +void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) {} } // namespace test diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index 7517c184..91c446b4 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -35,16 +35,17 @@ class MaidManager { MaidManager() {} template - routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); + routing::HandlePutReturn HandlePut(const routing::SourceAddress& from, const Data& data); }; -template template -routing::HandlePutPostReturn MaidManager::HandlePut( +template +template +routing::HandlePutReturn MaidManager::HandlePut( const routing::SourceAddress& /*source_address*/, const Data& data) { std::vector result; - result.push_back(std::make_pair(routing::Destination(routing::Address(data.Name())), - boost::none)); - return routing::HandlePutPostReturn(result); + result.push_back( + std::make_pair(routing::Destination(routing::Address(data.Name())), boost::none)); + return routing::HandlePutReturn(result); } @@ -54,7 +55,7 @@ class DataManager { DataManager() {} template - routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); + routing::HandlePutReturn HandlePut(const routing::SourceAddress& from, const Data& data); template routing::HandleGetReturn HandleGet(const routing::SourceAddress& from, const Identity& name); @@ -63,17 +64,19 @@ class DataManager { routing::CloseGroupDifference close_group_; }; -template template -routing::HandlePutPostReturn DataManager::HandlePut( - const routing::SourceAddress& /*from*/, const Data& data) { +template +template +routing::HandlePutReturn DataManager::HandlePut(const routing::SourceAddress& /*from*/, + const Data& data) { if (data_.find(data.name().value.string()) == std::end(data_)) data_.insert(std::make_pair(data.name().value.string(), data.data().string())); return boost::make_unexpected(MakeError(CommonErrors::success)); } -template template -routing::HandleGetReturn DataManager::HandleGet( - const routing::SourceAddress& /*from*/, const Identity& name) { +template +template +routing::HandleGetReturn DataManager::HandleGet(const routing::SourceAddress& /*from*/, + const Identity& name) { auto it(data_.find(name.string())); if (it != std::end(data_)) return routing::HandleGetReturn(std::vector(it->second.begin(), it->second.end())); @@ -82,8 +85,8 @@ routing::HandleGetReturn DataManager::HandleGet( // Helper function to parse data name and contents // FIXME this need discussion, adding it temporarily to progress -//template -//ParsedType ParseData(const SerialisedData& serialised_data) { +// template +// ParsedType ParseData(const SerialisedData& serialised_data) { // InputVectorStream binary_input_stream{serialised_data}; // typename ParsedType::Name name; // typename ParsedType::serialised_type contents; @@ -91,17 +94,17 @@ routing::HandleGetReturn DataManager::HandleGet( // return ParsedType(name, contents); //} -//template <> -//ImmutableData ParseData(const SerialisedData& serialised_data); +// template <> +// ImmutableData ParseData(const SerialisedData& serialised_data); class FakeVaultFacade : public MaidManager, public DataManager, public routing::RoutingNode { public: FakeVaultFacade() - : MaidManager(), - DataManager(), - routing::RoutingNode() {} + : MaidManager(), + DataManager(), + routing::RoutingNode() {} ~FakeVaultFacade() = default; @@ -112,14 +115,13 @@ class FakeVaultFacade : public MaidManager, Data::NameAndTypeId name_and_type_id); - routing::HandlePutPostReturn HandlePut(routing::SourceAddress from, - routing::Authority from_authority, - routing::Authority our_authority, - std::shared_ptr data); + routing::HandlePutReturn HandlePut(routing::SourceAddress from, routing::Authority from_authority, + routing::Authority our_authority, + std::shared_ptr data); bool HandlePost(const routing::SerialisedMessage& message); // not in local cache do upper layers have it (called when we are in target group) - template + template boost::expected HandleGet(routing::Address) { return boost::make_unexpected(MakeError(CommonErrors::no_such_element)); } From 76db82bc93810fece2cb33113f53b42208db23a3 Mon Sep 17 00:00:00 2001 From: prakash Date: Mon, 23 Mar 2015 17:46:56 +0000 Subject: [PATCH 59/72] minor updates --- include/maidsafe/routing/routing_node.h | 52 +++++++++++++--------- src/maidsafe/routing/connection_manager.cc | 2 +- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index e751c07a..10e434df 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -117,6 +117,7 @@ class RoutingNode { template void SendSwarmOrParallel(const DestinationAddress& destination, const SourceAddress& source, const MessageType& message, Authority authority); + void SendSwarmOrParallel(const Address& destination, const SerialisedMessage& serialised_message); template void SendToBootstrapNode(const DestinationAddress& destination, const SourceAddress& source, const MessageType& message, Authority authority); @@ -131,14 +132,7 @@ class RoutingNode { void OnBootstrap(asio::error_code, Contact, std::function); void PutOurPublicPmid(); - EndpointPair NextEndpointPair() { // FIXME(Peter) :06/03/2015 - if (!our_external_endpoint_) { - return EndpointPair(); - } - auto port = connection_manager_.AcceptingPort(); - return EndpointPair(Endpoint(GetLocalIp(), port), - Endpoint(our_external_endpoint_->address(), port)); - } + EndpointPair NextEndpointPair(); // this innocuous looking call will bootstrap the node and also be used if we spot close group // nodes appering or vanishing so its pretty important. void ConnectToCloseGroup(); @@ -225,6 +219,16 @@ void RoutingNode::PutOurPublicPmid() { }); } +template +EndpointPair RoutingNode::NextEndpointPair() { // FIXME(Peter) :06/03/2015 + if (!our_external_endpoint_) { + return EndpointPair(); + } + auto port = connection_manager_.AcceptingPort(); + return EndpointPair(Endpoint(GetLocalIp(), port), + Endpoint(our_external_endpoint_->address(), port)); +} + template template GetReturn RoutingNode::Get(Data::NameAndTypeId name_and_type_id, @@ -311,12 +315,9 @@ void RoutingNode::ConnectToCloseGroup() { template void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { - // LOG(kInfo) << OurId() << " MessageReceived from " << peer_id << " <<< "<< - // hex::Substr(serialised_message) << ">>>"; InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; - // Identity name; try { Parse(binary_input_stream, header, tag); } catch (const std::exception&) { @@ -327,7 +328,6 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri << " Msg from [ " << peer_id << " ] MessageId " << header.MessageId() << " tag: " << static_cast::type>(tag); - if (filter_.Check(header.FilterValue())) return; // already seen // add to filter as soon as posible @@ -362,13 +362,10 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri } // send to next node(s) even our close group (swarm mode) - for (const auto& target : connection_manager_.GetTarget(header.Destination().first)) { - connection_manager_.Send(target.id, serialised_message, [](asio::error_code error) { - if (error) { - LOG(kWarning) << "cannot send" << error.message(); - } - }); - } + SendSwarmOrParallel(header.Destination().first, serialised_message); + + // TODO(Prakash) cleanup aim to abstract relay logic here and may be use term routed message for + // response messages if (header.RelayedMessage() && (header.FromNode().data != OurId())) { // skip outgoing msgs std::set
connected_non_routing_nodes{connection_manager_.GetNonRoutingNodes()}; if (std::any_of( @@ -387,8 +384,7 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri // Drop message before Sentinel check if it is a direct message type (Connect, ConnectResponse) // and this node is in the group but the message destination is another group member node. - // TODO(Prakash) cleanup aim to abstract relay logic here and may be use term routed message for - // response messages + if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { if (header.Destination().first.data != OurId()) { // not for me if ((header.Destination().second) && (*header.Destination().second).data != OurId()) { @@ -510,6 +506,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h LOG(kVerbose) << "Sent ConnectResponse to " << temp; } }); + // connection_manager_.SendToNonRoutingNode(temp, message); // FIXME(Prakash) //////////////////////// std::weak_ptr destroy_guard = destroy_indicator_; @@ -681,6 +678,18 @@ void RoutingNode::SendSwarmOrParallel(const DestinationAddress& destinati } } +template +void RoutingNode::SendSwarmOrParallel(const Address& destination, + const SerialisedMessage& serialised_message) { + for (const auto& target : connection_manager_.GetTarget(destination)) { + connection_manager_.Send(target.id, serialised_message, [](asio::error_code error) { + if (error) { + LOG(kWarning) << "Connection manager cannot send" << error.message(); + } + }); + } +} + template template void RoutingNode::SendToBootstrapNode(const DestinationAddress& destination, @@ -697,6 +706,7 @@ void RoutingNode::SendToBootstrapNode(const DestinationAddress& destinati }); } + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 5d09927f..69080162 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -238,7 +238,7 @@ void ConnectionManager::StartReceiving() { void ConnectionManager::SendToNonRoutingNode(const Address& /*addr*/, const SerialisedMessage& /*message*/) { - // connections_->Send(addr, message, std::move(handler)); + // connections_->Send(addr, message, std::move(handler)); // FIXME(Prakash) // remove connection if failed } From 4e7ea963aec7a1889d30480a84f5e58f2a7b354f Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Tue, 24 Mar 2015 11:03:58 +0000 Subject: [PATCH 60/72] Revert "Renamed HandlePutPostReturn to HandlePutReturn." This reverts commit 9fb6d3c625caca90030fa8511d26db8cc2aaf639. --- include/maidsafe/routing/types.h | 9 +- .../tests/routing_vault_network_test.cc | 25 +++--- .../routing/tests/utils/fake_vault_facade.cc | 82 +++++++++---------- .../routing/tests/utils/fake_vault_facade.h | 52 ++++++------ 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/include/maidsafe/routing/types.h b/include/maidsafe/routing/types.h index 2a34a883..7954bfca 100644 --- a/include/maidsafe/routing/types.h +++ b/include/maidsafe/routing/types.h @@ -87,9 +87,10 @@ using FilterType = std::pair; using HandleGetReturn = boost::expected, std::vector>, maidsafe_error>; -using HandlePutReturn = boost::expected, maidsafe_error>; +using HandlePutPostReturn = boost::expected, maidsafe_error>; using HandlePostReturn = - boost::expected, std::vector>, maidsafe_error>; + boost::expected, std::vector>, + maidsafe_error>; using Endpoint = asio::ip::udp::endpoint; using Port = uint16_t; @@ -98,8 +99,8 @@ using CloseGroupDifference = std::pair, std::vector
; template -using AsyncResultHandler = typename asio::handler_type::type, - void(asio::error_code, Args...)>::type; +using AsyncResultHandler = + typename asio::handler_type::type, void(asio::error_code, Args...)>::type; template using AsyncResultReturn = diff --git a/src/maidsafe/routing/tests/routing_vault_network_test.cc b/src/maidsafe/routing/tests/routing_vault_network_test.cc index ca3720a1..4a148d3e 100644 --- a/src/maidsafe/routing/tests/routing_vault_network_test.cc +++ b/src/maidsafe/routing/tests/routing_vault_network_test.cc @@ -116,7 +116,7 @@ class MaidManager { public: using account_type = MaidManagerAccount; template - HandlePutReturn HandlePut(SourceAddress from, Identity data_name, T data) { + HandlePutPostReturn HandlePut(SourceAddress from, Identity data_name, T data) { auto found = static_cast(this)->maid_account(from.node_address); if (!found) return boost::make_unexpected(MakeError(VaultErrors::no_such_account)); @@ -270,7 +270,8 @@ class VaultFacade : public test::MaidManager, bool HandlePut(Address, SerialisedMessage) { return true; } // if the implementation allows any put of data in unauthenticated mode bool HandleUnauthenticatedPut(Address, SerialisedMessage) { return true; } - void HandleConnectionAdded(Address) {} + void HandleConnectionAdded(Address) { + } void HandleChurn(CloseGroupDifference diff) { MaidManager::HandleChurn(diff); @@ -290,20 +291,20 @@ TEST(VaultNetworkTest, FUNC_CreateNetPutGetData) { // other async actions (same with the tests below). - // LruCache cache(0, std::chrono::seconds(0)); +// LruCache cache(0, std::chrono::seconds(0)); - // RoutingNode n; +// RoutingNode n; - // NonEmptyString value(RandomAlphaNumericBytes(65)); - // Identity name(crypto::Hash(value)); - // MutableData a(name, value); - // ImmutableData b(value); +// NonEmptyString value(RandomAlphaNumericBytes(65)); +// Identity name(crypto::Hash(value)); +// MutableData a(name, value); +// ImmutableData b(value); - // Address from(MakeIdentity()); - // Address to(MakeIdentity()); +// Address from(MakeIdentity()); +// Address to(MakeIdentity()); - // n.Get(b.NameAndType(), [](asio::error_code /* error */) {}); - // n.Get(a.NameAndType(), [](asio::error_code /* error */) {}); +// n.Get(b.NameAndType(), [](asio::error_code /* error */) {}); +// n.Get(a.NameAndType(), [](asio::error_code /* error */) {}); // n.Put(to, b, [](asio::error_code /* error */) {}); // n.Put(to, a, [](asio::error_code /* error */) {}); diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index b6f9323b..e11bc7cf 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -29,8 +29,8 @@ namespace vault { namespace test { -// template <> -// ImmutableData ParseData(const SerialisedData& serialised_data) { +//template <> +//ImmutableData ParseData(const SerialisedData& serialised_data) { // auto digest_size(crypto::SHA512::DIGESTSIZE); // std::string name(serialised_data.begin(), serialised_data.begin() + digest_size); // std::string content(serialised_data.begin() + digest_size, serialised_data.end()); @@ -38,56 +38,56 @@ namespace test { // ImmutableData::serialised_type(NonEmptyString(content))); //} -routing::HandlePutReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, - routing::Authority from_authority, - routing::Authority our_authority, - std::shared_ptr data) { +routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, + routing::Authority from_authority, + routing::Authority our_authority, + std::shared_ptr data) { LOG(kVerbose) << "Received Put request from " << from.node_address.data << " with Data name " << data->Name() << " and type " << static_cast(data->TypeId()); (void)from_authority; (void)our_authority; - // switch (authority) { - // case routing::Authority::client_manager: - // if (from_authority != routing::Authority::client) - // break; - // if (name_and_type_id.type_id == detail::TypeId::value) - // return MaidManager::HandlePut(from, Parse(serialised_data)); - // else if (name_and_type_id.type_id == detail::TypeId::value) - // return MaidManager::HandlePut(from, Parse(serialised_data)); - // else if (name_and_type_id.type_id == detail::TypeId::value) - // return MaidManager::HandlePut(from, Parse(serialised_data)); - // case routing::Authority::nae_manager: - // if (from_authority != routing::Authority::client_manager) - // break; - // if (name_and_type_id.type_id == detail::TypeId::value) - // return DataManager::HandlePut(from, Parse(serialised_data)); - // else if (name_and_type_id.type_id == detail::TypeId::value) - // return DataManager::HandlePut(from, Parse(serialised_data)); - // break; - // default: - // break; - // } +// switch (authority) { +// case routing::Authority::client_manager: +// if (from_authority != routing::Authority::client) +// break; +// if (name_and_type_id.type_id == detail::TypeId::value) +// return MaidManager::HandlePut(from, Parse(serialised_data)); +// else if (name_and_type_id.type_id == detail::TypeId::value) +// return MaidManager::HandlePut(from, Parse(serialised_data)); +// else if (name_and_type_id.type_id == detail::TypeId::value) +// return MaidManager::HandlePut(from, Parse(serialised_data)); +// case routing::Authority::nae_manager: +// if (from_authority != routing::Authority::client_manager) +// break; +// if (name_and_type_id.type_id == detail::TypeId::value) +// return DataManager::HandlePut(from, Parse(serialised_data)); +// else if (name_and_type_id.type_id == detail::TypeId::value) +// return DataManager::HandlePut(from, Parse(serialised_data)); +// break; +// default: +// break; +// } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } routing::HandleGetReturn FakeVaultFacade::HandleGet(routing::SourceAddress /*from*/, - routing::Authority /*from_authority*/, - routing::Authority /*authority*/, - Data::NameAndTypeId /*name_and_type_id*/) { - // switch (authority) { - // case routing::Authority::nae_manager: - // if (name_and_type_id.type_id == detail::TypeId::value) - // return DataManager::template HandleGet(from, data_name); - // else if (name_and_type_id.type_id == detail::TypeId::value) - // return DataManager::template HandleGet(from, data_name); - // break; - // default: - // break; - // } + routing::Authority /*from_authority*/, routing::Authority /*authority*/, + Data::NameAndTypeId /*name_and_type_id*/) { +// switch (authority) { +// case routing::Authority::nae_manager: +// if (name_and_type_id.type_id == detail::TypeId::value) +// return DataManager::template HandleGet(from, data_name); +// else if (name_and_type_id.type_id == detail::TypeId::value) +// return DataManager::template HandleGet(from, data_name); +// break; +// default: +// break; +// } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } -void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) {} +void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) { +} } // namespace test diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index 91c446b4..7517c184 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -35,17 +35,16 @@ class MaidManager { MaidManager() {} template - routing::HandlePutReturn HandlePut(const routing::SourceAddress& from, const Data& data); + routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); }; -template -template -routing::HandlePutReturn MaidManager::HandlePut( +template template +routing::HandlePutPostReturn MaidManager::HandlePut( const routing::SourceAddress& /*source_address*/, const Data& data) { std::vector result; - result.push_back( - std::make_pair(routing::Destination(routing::Address(data.Name())), boost::none)); - return routing::HandlePutReturn(result); + result.push_back(std::make_pair(routing::Destination(routing::Address(data.Name())), + boost::none)); + return routing::HandlePutPostReturn(result); } @@ -55,7 +54,7 @@ class DataManager { DataManager() {} template - routing::HandlePutReturn HandlePut(const routing::SourceAddress& from, const Data& data); + routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); template routing::HandleGetReturn HandleGet(const routing::SourceAddress& from, const Identity& name); @@ -64,19 +63,17 @@ class DataManager { routing::CloseGroupDifference close_group_; }; -template -template -routing::HandlePutReturn DataManager::HandlePut(const routing::SourceAddress& /*from*/, - const Data& data) { +template template +routing::HandlePutPostReturn DataManager::HandlePut( + const routing::SourceAddress& /*from*/, const Data& data) { if (data_.find(data.name().value.string()) == std::end(data_)) data_.insert(std::make_pair(data.name().value.string(), data.data().string())); return boost::make_unexpected(MakeError(CommonErrors::success)); } -template -template -routing::HandleGetReturn DataManager::HandleGet(const routing::SourceAddress& /*from*/, - const Identity& name) { +template template +routing::HandleGetReturn DataManager::HandleGet( + const routing::SourceAddress& /*from*/, const Identity& name) { auto it(data_.find(name.string())); if (it != std::end(data_)) return routing::HandleGetReturn(std::vector(it->second.begin(), it->second.end())); @@ -85,8 +82,8 @@ routing::HandleGetReturn DataManager::HandleGet(const routing::SourceAdd // Helper function to parse data name and contents // FIXME this need discussion, adding it temporarily to progress -// template -// ParsedType ParseData(const SerialisedData& serialised_data) { +//template +//ParsedType ParseData(const SerialisedData& serialised_data) { // InputVectorStream binary_input_stream{serialised_data}; // typename ParsedType::Name name; // typename ParsedType::serialised_type contents; @@ -94,17 +91,17 @@ routing::HandleGetReturn DataManager::HandleGet(const routing::SourceAdd // return ParsedType(name, contents); //} -// template <> -// ImmutableData ParseData(const SerialisedData& serialised_data); +//template <> +//ImmutableData ParseData(const SerialisedData& serialised_data); class FakeVaultFacade : public MaidManager, public DataManager, public routing::RoutingNode { public: FakeVaultFacade() - : MaidManager(), - DataManager(), - routing::RoutingNode() {} + : MaidManager(), + DataManager(), + routing::RoutingNode() {} ~FakeVaultFacade() = default; @@ -115,13 +112,14 @@ class FakeVaultFacade : public MaidManager, Data::NameAndTypeId name_and_type_id); - routing::HandlePutReturn HandlePut(routing::SourceAddress from, routing::Authority from_authority, - routing::Authority our_authority, - std::shared_ptr data); + routing::HandlePutPostReturn HandlePut(routing::SourceAddress from, + routing::Authority from_authority, + routing::Authority our_authority, + std::shared_ptr data); bool HandlePost(const routing::SerialisedMessage& message); // not in local cache do upper layers have it (called when we are in target group) - template + template boost::expected HandleGet(routing::Address) { return boost::make_unexpected(MakeError(CommonErrors::no_such_element)); } From af3b1fb9c94329a6fd03f3a774aecde105ccffa8 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Tue, 24 Mar 2015 11:09:41 +0000 Subject: [PATCH 61/72] "Fix" vault facade test. --- src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index 3c3acdeb..079a726b 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -43,7 +43,7 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { EXPECT_NO_THROW(put_future.get()); passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); std::shared_ptr public_maid(new passport::PublicMaid(maid_and_signer.first)); - put_future = vault1.Put(public_maid, asio::use_future); + put_future = vault2.Put(public_maid, asio::use_future); EXPECT_NO_THROW(put_future.get()); @@ -52,7 +52,7 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { std::error_code error; vault2.Put(immutable_data, yield[error]); EXPECT_FALSE(error) << error.message(); - vault1.Put(public_maid, yield[error]); + vault2.Put(public_maid, yield[error]); EXPECT_FALSE(error) << error.message(); }); From 20c2c4934e6014a261f0a578ff4d5bd8dd531880 Mon Sep 17 00:00:00 2001 From: Fraser Hutchison Date: Tue, 24 Mar 2015 11:41:33 +0000 Subject: [PATCH 62/72] Style fixes. --- include/maidsafe/routing/routing_node.h | 7 +- include/maidsafe/routing/types.h | 15 ++-- src/maidsafe/routing/apply_tuple.h | 13 ++-- src/maidsafe/routing/connection_manager.cc | 2 +- src/maidsafe/routing/connection_manager.h | 4 +- src/maidsafe/routing/connections.h | 17 ++--- .../routing/tests/routing_connections_test.cc | 61 ++++++++------- .../tests/routing_fake_vault_facade_test.cc | 14 ++-- .../routing/tests/utils/fake_vault_facade.cc | 76 +++++++++---------- .../routing/tests/utils/fake_vault_facade.h | 41 +++++----- src/maidsafe/routing/timer.h | 8 +- 11 files changed, 130 insertions(+), 128 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 114dc1de..cc8b5aab 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -303,7 +304,7 @@ PostReturn RoutingNode::Post(Address to, FunctorType fun template void RoutingNode::ConnectToCloseGroup() { FindGroup find_group_message(NodeAddress(OurId()), OurId()); - if (bootstrap_node_) { // TODO cleanup + if (bootstrap_node_) { // TODO(Team) cleanup SendToBootstrapNode(std::make_pair(Destination(OurId()), boost::none), OurSourceAddress(), find_group_message, Authority::node); } else { @@ -475,7 +476,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h SourceAddress(OurSourceAddress()), original_header.MessageId(), Authority::node, asymm::Sign(asymm::PlainText(Serialise(respond)), our_fob_.private_key())); - if (bootstrap_node_) { // TODO cleanup + if (bootstrap_node_) { // TODO(Team) cleanup auto message = Serialise(header, MessageToTag::value(), respond); connection_manager_.Send(*bootstrap_node_, std::move(message), [](asio::error_code error) { if (error) { @@ -600,7 +601,7 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, if (!connection_manager_.SuggestNodeToAdd(node_id)) continue; Connect connect_message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); - if (bootstrap_node_) { // TODO cleanup + if (bootstrap_node_) { // TODO(Team) cleanup SendToBootstrapNode(std::make_pair(Destination(node_id), boost::none), OurSourceAddress(), connect_message, Authority::nae_manager); } else { diff --git a/include/maidsafe/routing/types.h b/include/maidsafe/routing/types.h index 7954bfca..9680c467 100644 --- a/include/maidsafe/routing/types.h +++ b/include/maidsafe/routing/types.h @@ -48,7 +48,7 @@ namespace routing { static const size_t GroupSize = 23; static const size_t QuorumSize = 19; -enum class FromType : int32_t { +enum class FromType : std::int32_t { client_manager, nae_manager, node_manager, @@ -58,7 +58,7 @@ enum class FromType : int32_t { node }; -enum class Authority : int32_t { +enum class Authority : std::int32_t { client_manager, nae_manager, node_manager, @@ -68,7 +68,7 @@ enum class Authority : int32_t { }; using Address = Identity; -using MessageId = uint32_t; +using MessageId = std::uint32_t; using Destination = TaggedValue; using ReplyToAddress = TaggedValue; using DestinationAddress = std::pair>; @@ -89,18 +89,17 @@ using HandleGetReturn = maidsafe_error>; using HandlePutPostReturn = boost::expected, maidsafe_error>; using HandlePostReturn = - boost::expected, std::vector>, - maidsafe_error>; + boost::expected, std::vector>, maidsafe_error>; using Endpoint = asio::ip::udp::endpoint; -using Port = uint16_t; +using Port = std::uint16_t; using SerialisedMessage = std::vector; using CloseGroupDifference = std::pair, std::vector
>; using PublicKeyId = std::pair; template -using AsyncResultHandler = - typename asio::handler_type::type, void(asio::error_code, Args...)>::type; +using AsyncResultHandler = typename asio::handler_type::type, + void(asio::error_code, Args...)>::type; template using AsyncResultReturn = diff --git a/src/maidsafe/routing/apply_tuple.h b/src/maidsafe/routing/apply_tuple.h index 89419c92..bb79906a 100644 --- a/src/maidsafe/routing/apply_tuple.h +++ b/src/maidsafe/routing/apply_tuple.h @@ -47,14 +47,13 @@ inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup, template inline MAIDSAFE_CONSTEXPR auto ApplyTuple(F&& f, const std::tuple& tup) - -> decltype(helper::ApplyTuple(std::forward(f), tup, helper::GeneratedSequence{})) { - return helper::ApplyTuple(std::forward(f), - tup, - helper::GeneratedSequence{}); + -> decltype(helper::ApplyTuple(std::forward(f), tup, + helper::GeneratedSequence{})) { + return helper::ApplyTuple(std::forward(f), tup, helper::GeneratedSequence{}); } -} // namespace routing +} // namespace routing -} // namespace maidsafe +} // namespace maidsafe -#endif // MAIDSAFE_ROUTING_APPLY_TUPLE_H_ +#endif // MAIDSAFE_ROUTING_APPLY_TUPLE_H_ diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 69080162..fdeec390 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -86,7 +86,7 @@ std::set
ConnectionManager::GetNonRoutingNodes() const { // routing_table_.DropNode(their_id); // // FIXME(Prakash) remove connection ? // return GroupChanged(); -//} +// } void ConnectionManager::DropNode(const Address& their_id) { connections_->Drop(their_id); } void ConnectionManager::StartAccepting() { diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index b41c91b8..4e3b5d0b 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -127,7 +127,7 @@ class ConnectionManager { void SendToNonRoutingNode(const Address&, const SerialisedMessage&); // remove connection if fails - unsigned short AcceptingPort() const { return our_accept_port_; } + Port AcceptingPort() const { return our_accept_port_; } template void Connect(asio::ip::udp::endpoint, Handler); @@ -147,7 +147,7 @@ class ConnectionManager { private: asio::io_service& io_service_; mutable std::mutex mutex_; - unsigned short our_accept_port_; + Port our_accept_port_; RoutingTable routing_table_; std::set
connected_non_routing_nodes_; // clients & bootstrapping nodes OnReceive on_receive_; diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index a63d613b..614a9e34 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "asio/io_service.hpp" @@ -82,8 +83,7 @@ class Connections { // The secont argument is an ugly C-style return of the actual port that has been // chosen. TODO: Try to return it using a proper C++ way. template - AsyncResultReturn Accept(unsigned short port, unsigned short* chosen_port, - Token&&); + AsyncResultReturn Accept(Port port, Port* chosen_port, Token&&); void Drop(const Address& their_id); @@ -113,7 +113,7 @@ class Connections { std::function on_receive_; std::function on_drop_; - std::map> acceptors_; // NOLINT + std::map> acceptors_; // NOLINT std::map> connections_; std::map id_to_endpoint_map_; @@ -276,18 +276,17 @@ AsyncResultReturn Connections::Connect(Endpoi } template -AsyncResultReturn Connections::Accept(unsigned short port, - unsigned short* chosen_port, +AsyncResultReturn Connections::Accept(Port port, + Port* chosen_port, Token&& token) { using Handler = AsyncResultHandler; Handler handler(std::forward(token)); asio::async_result result(handler); - auto loopback = - [](unsigned short port) { return crux::endpoint(boost::asio::ip::udp::v4(), port); }; + auto loopback = [](Port port) { return crux::endpoint(boost::asio::ip::udp::v4(), port); }; - // TODO(PeterJ):Make sure this operation is thread safe in crux. + // TODO(PeterJ) Make sure this operation is thread safe in crux. std::shared_ptr acceptor; try { @@ -410,7 +409,7 @@ void Connections::post(Handler&& handler, Args&&... args) { inline void Connections::Drop(const Address& their_id) { get_io_service().post([=]() { - // TODO: Migth it be that it is in connections_ but not in the id_to_endpoint_map_? + // TODO(Team): Might it be that it is in connections_ but not in the id_to_endpoint_map_? // I.e. that above layers would wan't to remove by ID nodes which were not // yet connected? auto i = id_to_endpoint_map_.find(their_id); diff --git a/src/maidsafe/routing/tests/routing_connections_test.cc b/src/maidsafe/routing/tests/routing_connections_test.cc index 19698dfc..883a8802 100644 --- a/src/maidsafe/routing/tests/routing_connections_test.cc +++ b/src/maidsafe/routing/tests/routing_connections_test.cc @@ -51,37 +51,35 @@ TEST(ConnectionsTest, FUNC_TwoConnections) { Connections c1(ios, c1_id); Connections c2(ios, c2_id); - unsigned short port = 8080; - - c1.Accept(port, nullptr, - [&](asio::error_code error, Connections::AcceptResult result) { - ASSERT_FALSE(error); - ASSERT_EQ(result.his_address, c2.OurId()); - ASSERT_EQ(result.our_endpoint.port(), port); - - c1.Send(result.his_address, - str_to_msg("hello"), - [&](asio::error_code error) { - ASSERT_FALSE(error); - c1.Shutdown(); - c1_finished = true; - }); - }); + Port port = 8080; + + c1.Accept(port, nullptr, [&](asio::error_code error, Connections::AcceptResult result) { + ASSERT_FALSE(error); + ASSERT_EQ(result.his_address, c2.OurId()); + ASSERT_EQ(result.our_endpoint.port(), port); + + c1.Send(result.his_address, str_to_msg("hello"), [&](asio::error_code error) { + ASSERT_FALSE(error); + c1.Shutdown(); + c1_finished = true; + }); + }); c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), - [&](asio::error_code error, Connections::ConnectResult result) { - ASSERT_FALSE(error); - ASSERT_EQ(result.his_address, c1.OurId()); + [&](asio::error_code error, Connections::ConnectResult result) { + ASSERT_FALSE(error); + ASSERT_EQ(result.his_address, c1.OurId()); - c2.Receive([&, result](asio::error_code error, Connections::ReceiveResult recv_result) { - ASSERT_FALSE(error); - ASSERT_EQ(recv_result.his_address, result.his_address); - ASSERT_EQ(msg_to_str(recv_result.message), "hello"); + c2.Receive( + [&, result](asio::error_code error, Connections::ReceiveResult recv_result) { + ASSERT_FALSE(error); + ASSERT_EQ(recv_result.his_address, result.his_address); + ASSERT_EQ(msg_to_str(recv_result.message), "hello"); - c2.Shutdown(); - c2_finished = true; - }); - }); + c2.Shutdown(); + c2_finished = true; + }); + }); ios.run(); @@ -99,12 +97,13 @@ TEST(ConnectionsTest, FUNC_TwoConnectionsWithFutures) { std::thread thread([&]() { ios.run(); }); - unsigned short port = 8080; + Port port = 8080; - auto accept_f = c1.Accept(port, nullptr, asio::use_future); - auto connect_f = c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), asio::use_future); + auto accept_f = c1.Accept(port, nullptr, asio::use_future); + auto connect_f = + c2.Connect(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), port), asio::use_future); - auto accept_result = accept_f.get(); + auto accept_result = accept_f.get(); auto connect_result = connect_f.get(); ASSERT_EQ(accept_result.his_address, c2.OurId()); diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index 079a726b..ddf48699 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -37,9 +37,9 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { LOG(kInfo) << "================================================================================="; - std::shared_ptr immutable_data(new ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50)))); - std::future put_future( - vault2.Put(immutable_data, asio::use_future)); + std::shared_ptr immutable_data( + new ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50)))); + std::future put_future(vault2.Put(immutable_data, asio::use_future)); EXPECT_NO_THROW(put_future.get()); passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); std::shared_ptr public_maid(new passport::PublicMaid(maid_and_signer.first)); @@ -60,12 +60,12 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { asio_service.Stop(); } -//TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { +// TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { // using endpoint = asio::ip::udp::endpoint; // using address = asio::ip::address_v4; // vault::test::FakeVaultFacade facade1; -// std::vector> vaults(2); -// unsigned short port(5483); +// std::vector> vaults(2); +// Port port(5483); // for (auto& vault : vaults) // vault.second = port++; // for (auto& vault : vaults) @@ -89,7 +89,7 @@ TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { // [](maidsafe_error error) { // ASSERT_EQ(error.code(), make_error_code(CommonErrors::success)); // }); -//} +// } } // namespace test diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc index e11bc7cf..ace923c6 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.cc +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.cc @@ -29,14 +29,14 @@ namespace vault { namespace test { -//template <> -//ImmutableData ParseData(const SerialisedData& serialised_data) { +// template <> +// ImmutableData ParseData(const SerialisedData& serialised_data) { // auto digest_size(crypto::SHA512::DIGESTSIZE); // std::string name(serialised_data.begin(), serialised_data.begin() + digest_size); // std::string content(serialised_data.begin() + digest_size, serialised_data.end()); // return ImmutableData(ImmutableData::Name(Identity(name)), // ImmutableData::serialised_type(NonEmptyString(content))); -//} +// } routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress from, routing::Authority from_authority, @@ -46,48 +46,48 @@ routing::HandlePutPostReturn FakeVaultFacade::HandlePut(routing::SourceAddress f << data->Name() << " and type " << static_cast(data->TypeId()); (void)from_authority; (void)our_authority; -// switch (authority) { -// case routing::Authority::client_manager: -// if (from_authority != routing::Authority::client) -// break; -// if (name_and_type_id.type_id == detail::TypeId::value) -// return MaidManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return MaidManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return MaidManager::HandlePut(from, Parse(serialised_data)); -// case routing::Authority::nae_manager: -// if (from_authority != routing::Authority::client_manager) -// break; -// if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::HandlePut(from, Parse(serialised_data)); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::HandlePut(from, Parse(serialised_data)); -// break; -// default: -// break; -// } + // switch (authority) { + // case routing::Authority::client_manager: + // if (from_authority != routing::Authority::client) + // break; + // if (name_and_type_id.type_id == detail::TypeId::value) + // return MaidManager::HandlePut(from, Parse(serialised_data)); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return MaidManager::HandlePut(from, Parse(serialised_data)); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return MaidManager::HandlePut(from, Parse(serialised_data)); + // case routing::Authority::nae_manager: + // if (from_authority != routing::Authority::client_manager) + // break; + // if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::HandlePut(from, Parse(serialised_data)); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::HandlePut(from, Parse(serialised_data)); + // break; + // default: + // break; + // } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } routing::HandleGetReturn FakeVaultFacade::HandleGet(routing::SourceAddress /*from*/, - routing::Authority /*from_authority*/, routing::Authority /*authority*/, - Data::NameAndTypeId /*name_and_type_id*/) { -// switch (authority) { -// case routing::Authority::nae_manager: -// if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::template HandleGet(from, data_name); -// else if (name_and_type_id.type_id == detail::TypeId::value) -// return DataManager::template HandleGet(from, data_name); -// break; -// default: -// break; -// } + routing::Authority /*from_authority*/, + routing::Authority /*authority*/, + Data::NameAndTypeId /*name_and_type_id*/) { + // switch (authority) { + // case routing::Authority::nae_manager: + // if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::template HandleGet(from, data_name); + // else if (name_and_type_id.type_id == detail::TypeId::value) + // return DataManager::template HandleGet(from, data_name); + // break; + // default: + // break; + // } return boost::make_unexpected(MakeError(VaultErrors::failed_to_handle_request)); } -void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) { -} +void FakeVaultFacade::HandleChurn(routing::CloseGroupDifference /*diff*/) {} } // namespace test diff --git a/src/maidsafe/routing/tests/utils/fake_vault_facade.h b/src/maidsafe/routing/tests/utils/fake_vault_facade.h index 7517c184..5c5aec99 100644 --- a/src/maidsafe/routing/tests/utils/fake_vault_facade.h +++ b/src/maidsafe/routing/tests/utils/fake_vault_facade.h @@ -20,6 +20,8 @@ #define MAIDSAFE_ROUTING_TESTS_UTILS_FAKE_VAULT_FACADE_H_ #include +#include +#include #include "maidsafe/routing/routing_node.h" @@ -38,12 +40,13 @@ class MaidManager { routing::HandlePutPostReturn HandlePut(const routing::SourceAddress& from, const Data& data); }; -template template +template +template routing::HandlePutPostReturn MaidManager::HandlePut( const routing::SourceAddress& /*source_address*/, const Data& data) { std::vector result; - result.push_back(std::make_pair(routing::Destination(routing::Address(data.Name())), - boost::none)); + result.push_back( + std::make_pair(routing::Destination(routing::Address(data.Name())), boost::none)); return routing::HandlePutPostReturn(result); } @@ -63,17 +66,19 @@ class DataManager { routing::CloseGroupDifference close_group_; }; -template template -routing::HandlePutPostReturn DataManager::HandlePut( - const routing::SourceAddress& /*from*/, const Data& data) { +template +template +routing::HandlePutPostReturn DataManager::HandlePut(const routing::SourceAddress& /*from*/, + const Data& data) { if (data_.find(data.name().value.string()) == std::end(data_)) data_.insert(std::make_pair(data.name().value.string(), data.data().string())); return boost::make_unexpected(MakeError(CommonErrors::success)); } -template template -routing::HandleGetReturn DataManager::HandleGet( - const routing::SourceAddress& /*from*/, const Identity& name) { +template +template +routing::HandleGetReturn DataManager::HandleGet(const routing::SourceAddress& /*from*/, + const Identity& name) { auto it(data_.find(name.string())); if (it != std::end(data_)) return routing::HandleGetReturn(std::vector(it->second.begin(), it->second.end())); @@ -82,26 +87,26 @@ routing::HandleGetReturn DataManager::HandleGet( // Helper function to parse data name and contents // FIXME this need discussion, adding it temporarily to progress -//template -//ParsedType ParseData(const SerialisedData& serialised_data) { +// template +// ParsedType ParseData(const SerialisedData& serialised_data) { // InputVectorStream binary_input_stream{serialised_data}; // typename ParsedType::Name name; // typename ParsedType::serialised_type contents; // Parse(binary_input_stream, name, contents); // return ParsedType(name, contents); -//} +// } -//template <> -//ImmutableData ParseData(const SerialisedData& serialised_data); +// template <> +// ImmutableData ParseData(const SerialisedData& serialised_data); class FakeVaultFacade : public MaidManager, public DataManager, public routing::RoutingNode { public: FakeVaultFacade() - : MaidManager(), - DataManager(), - routing::RoutingNode() {} + : MaidManager(), + DataManager(), + routing::RoutingNode() {} ~FakeVaultFacade() = default; @@ -119,7 +124,7 @@ class FakeVaultFacade : public MaidManager, bool HandlePost(const routing::SerialisedMessage& message); // not in local cache do upper layers have it (called when we are in target group) - template + template boost::expected HandleGet(routing::Address) { return boost::make_unexpected(MakeError(CommonErrors::no_such_element)); } diff --git a/src/maidsafe/routing/timer.h b/src/maidsafe/routing/timer.h index 032010b3..b2e64811 100644 --- a/src/maidsafe/routing/timer.h +++ b/src/maidsafe/routing/timer.h @@ -30,11 +30,11 @@ namespace routing { class Timer { public: - Timer(asio::io_service&); + explicit Timer(asio::io_service& ios); ~Timer(); template - void async_wait(asio::steady_timer::duration, Handler&&); + void async_wait(asio::steady_timer::duration duration, Handler&& handler); void cancel(); @@ -68,8 +68,8 @@ inline void Timer::cancel() { timer_.cancel(); } -} // routing namespace +} // namespace routing -} // maidsafe namespace +} // namespace maidsafe #endif // MAIDSAFE_ROUTING_TIMER_H_ From da9a19ed7ae97ea5456ad66da86ff968cc9a7fbe Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 24 Mar 2015 14:14:01 +0100 Subject: [PATCH 63/72] Message to ostream serialization for easier debugging --- include/maidsafe/routing/routing_node.h | 19 ++++++++++--------- include/maidsafe/routing/source_address.h | 17 +++++++++++++++++ src/maidsafe/routing/connections.h | 3 +++ src/maidsafe/routing/message_header.h | 19 +++++++++++++++++++ src/maidsafe/routing/messages/connect.h | 5 +++++ .../routing/messages/connect_response.h | 7 +++++++ src/maidsafe/routing/messages/find_group.h | 5 +++++ .../routing/messages/find_group_response.h | 16 ++++++++++++++++ 8 files changed, 82 insertions(+), 9 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index e1c6b440..fe3ec65f 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -323,9 +323,10 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri LOG(kError) << "header failure." << boost::current_exception_diagnostic_information(); return; } - LOG(kVerbose) << " [ " << OurId() << " ] " - << " Msg from [ " << peer_id << " ] MessageId " << header.MessageId() - << " tag: " << static_cast::type>(tag); + LOG(kVerbose) << OurId() + << " Msg from " << peer_id + << " tag:" << static_cast::type>(tag) + << " " << header; if (filter_.Check(header.FilterValue())) @@ -467,7 +468,7 @@ void RoutingNode::ConnectionLost(boost::optional di // reply with our details; template void RoutingNode::HandleMessage(Connect connect, MessageHeader original_header) { - LOG(kInfo) << "HandleMessage -- Connect msg .. need to connect to " << connect.requester_id(); + LOG(kInfo) << OurId() << " HandleMessage " << connect; if (!connection_manager_.SuggestNodeToAdd(connect.requester_id())) return; auto targets(connection_manager_.GetTarget(connect.requester_id())); @@ -527,8 +528,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h template void RoutingNode::HandleMessage(ConnectResponse connect_response) { - LOG(kInfo) << "HandleMessage -- ConnectResponse msg .. need to connect to " - << connect_response.receiver_id(); + LOG(kInfo) << OurId() << " HandleMessage " << connect_response; if (!connection_manager_.SuggestNodeToAdd(connect_response.receiver_id())) return; @@ -556,6 +556,7 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { template void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader original_header) { + LOG(kInfo) << OurId() << " HandleMessage " << find_group; auto close_group = connection_manager_.OurCloseGroup(); // add ourselves std::vector group; @@ -592,13 +593,13 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi } template -void RoutingNode::HandleMessage(FindGroupResponse find_group_reponse, +void RoutingNode::HandleMessage(FindGroupResponse find_group_response, MessageHeader /* original_header */) { // this is called to get our group on bootstrap, we will try and connect to each of these nodes // Only other reason is to allow the sentinel to check signatures and those calls will just fall // through here. - LOG(kInfo) << "HandleMessage -- FindGroupResponse msg"; - for (const auto node_pmid : find_group_reponse.group()) { + LOG(kInfo) << OurId() << " HandleMessage " << find_group_response; + for (const auto node_pmid : find_group_response.group()) { Address node_id(node_pmid.Name()); if (!connection_manager_.SuggestNodeToAdd(node_id)) continue; diff --git a/include/maidsafe/routing/source_address.h b/include/maidsafe/routing/source_address.h index e04acbed..8c97b70b 100644 --- a/include/maidsafe/routing/source_address.h +++ b/include/maidsafe/routing/source_address.h @@ -86,6 +86,23 @@ inline bool operator>=(const SourceAddress& lhs, const SourceAddress& rhs) { return !operator<(lhs, rhs); } +inline std::ostream& operator<<(std::ostream& os, const SourceAddress& addr) { + os << "(SourceAddress node:" << reinterpret_cast(addr.node_address) << ", "; + if (addr.group_address) { + os << "group:" << reinterpret_cast(*addr.group_address); + } + else { + os << "group:none"; + } + if (addr.reply_to_address) { + os << ", reply_to:" << reinterpret_cast(*addr.reply_to_address); + } + else { + os << ", reply_to:none"; + } + return os << ")"; +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index a63d613b..988a6932 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -215,8 +215,11 @@ AsyncResultReturn Connections::Connect(Endpoi Handler handler(std::forward(token)); asio::async_result result(handler); + std::cerr << "Connections::Connect(" << endpoint << ")\n"; + get_io_service().post([=]() mutable { crux::endpoint unspecified_ep; + if (endpoint.address().is_v4()) unspecified_ep = crux::endpoint(boost::asio::ip::udp::v4(), 0); else diff --git a/src/maidsafe/routing/message_header.h b/src/maidsafe/routing/message_header.h index 7f3ab908..5dd1b59e 100644 --- a/src/maidsafe/routing/message_header.h +++ b/src/maidsafe/routing/message_header.h @@ -173,6 +173,25 @@ class MessageHeader { boost::optional signature_; }; +inline +std::ostream& operator<<(std::ostream& os, const MessageHeader& hdr) { + return os << "(Header src:" << hdr.Source() + << ", dst:("; + + auto dst = hdr.Destination(); + + os << reinterpret_cast(dst.first) << ", reply_to:"; + + if (dst.second) { + os << reinterpret_cast(*dst.second) << ")"; + } + else { + os << "none)"; + } + + return os << ", id:" << hdr.MessageId() << ", ...)"; +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/messages/connect.h b/src/maidsafe/routing/messages/connect.h index bc9079db..96e0645a 100644 --- a/src/maidsafe/routing/messages/connect.h +++ b/src/maidsafe/routing/messages/connect.h @@ -75,6 +75,11 @@ class Connect { passport::PublicPmid requester_fob_; }; +inline std::ostream& operator<<(std::ostream& os, const Connect& msg) { + return os << "(Connect " << msg.requester_endpoints() << ", " + << msg.requester_id() << ", " << msg.receiver_id() << ", ...)"; +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/messages/connect_response.h b/src/maidsafe/routing/messages/connect_response.h index e66c574a..fc00112f 100644 --- a/src/maidsafe/routing/messages/connect_response.h +++ b/src/maidsafe/routing/messages/connect_response.h @@ -80,6 +80,13 @@ class ConnectResponse { passport::PublicPmid receiver_fob_; }; +inline std::ostream& operator<<(std::ostream& os, const ConnectResponse& msg) { + return os << "(ConnectResponse rq:" << msg.requester_endpoints() << ", " + << "rc:" << msg.receiver_endpoints() + << ", rq:" << msg.requester_id() + << ", rc:" << msg.receiver_id() << ")"; +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/messages/find_group.h b/src/maidsafe/routing/messages/find_group.h index 89ea2979..63526c86 100644 --- a/src/maidsafe/routing/messages/find_group.h +++ b/src/maidsafe/routing/messages/find_group.h @@ -60,6 +60,11 @@ class FindGroup { Address target_id_; }; +inline std::ostream& operator<<(std::ostream& os, const FindGroup& msg) { + return os << "(FindGroup requester:" << static_cast
(msg.requester_id()) + << ", target:" << msg.target_id() << ")"; +} + } // namespace routing } // namespace maidsafe diff --git a/src/maidsafe/routing/messages/find_group_response.h b/src/maidsafe/routing/messages/find_group_response.h index a2745b50..0bb5f66a 100644 --- a/src/maidsafe/routing/messages/find_group_response.h +++ b/src/maidsafe/routing/messages/find_group_response.h @@ -64,6 +64,22 @@ class FindGroupResponse { std::vector group_; }; +inline std::ostream& operator<<(std::ostream& os, const FindGroupResponse& msg) { + os << "(FindGroupResponse target:" << msg.target_id() + << ", group:{"; + + auto group = msg.group(); + + for (auto i = group.begin(); i != group.end();) { + os << i->Name(); + if (++i != group.end()) { + os << ","; + } + } + + return os << "})"; +} + } // namespace routing } // namespace maidsafe From 9549662737524d21e737f9d30a814d0ee1ec0ba6 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 24 Mar 2015 16:04:23 +0100 Subject: [PATCH 64/72] RoutingFakeVaultFacade test now passes. --- include/maidsafe/routing/routing_node.h | 54 +++++++++++++------------ 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 8fd66c21..ddfc0283 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -181,27 +181,32 @@ RoutingNode::RoutingNode() template void RoutingNode::StartBootstrap() { - auto handler = [=](asio::error_code error, Address peer_addr, Endpoint /*our_public_endpoint*/) { - if (error) { - LOG(kWarning) << "Cannot connect to bootstrap endpoint < " << peer_addr << " >" - << error.message(); - // TODO(Team): try connect to bootstrap contacts and other options - // (hardcoded endpoints).on failure keep retrying all options forever - return; - } - LOG(kInfo) << "Bootstrapped with " << peer_addr; - // FIXME(Team): Thread safety. - bootstrap_node_ = peer_addr; - // bootstrap_endpoint_ = our_endpoint; this will not required if - // connection manager has this connection - PutOurPublicPmid(); - ConnectToCloseGroup(); - }; // try connect to any local nodes (5483) Expect to be told Node_Id Endpoint live_port_ep(GetLocalIp(), kLivePort); + // skip trying to bootstrap off self - if (connection_manager_.AcceptingPort() != kLivePort) - connection_manager_.Connect(live_port_ep, handler); + if (connection_manager_.AcceptingPort() == kLivePort) { + return; + } + + connection_manager_.Connect(live_port_ep, + [=](asio::error_code error, Address peer_addr, Endpoint our_public_endpoint) { + if (error) { + LOG(kWarning) << "Cannot connect to bootstrap endpoint < " << peer_addr << " >" + << error.message(); + // TODO(Team): try connect to bootstrap contacts and other options + // (hardcoded endpoints).on failure keep retrying all options forever + return; + } + LOG(kInfo) << "Bootstrapped with " << peer_addr; + // FIXME(Team): Thread safety. + bootstrap_node_ = peer_addr; + our_external_endpoint_ = our_public_endpoint; + // bootstrap_endpoint_ = our_endpoint; this will not required if + // connection manager has this connection + PutOurPublicPmid(); + ConnectToCloseGroup(); + }); // auto bootstrap_contacts = bootstrap_handler_.ReadBootstrapContacts(); } @@ -221,13 +226,12 @@ void RoutingNode::PutOurPublicPmid() { } template -EndpointPair RoutingNode::NextEndpointPair() { // FIXME(Peter) :06/03/2015 - if (!our_external_endpoint_) { - return EndpointPair(); - } +EndpointPair RoutingNode::NextEndpointPair() { auto port = connection_manager_.AcceptingPort(); + return EndpointPair(Endpoint(GetLocalIp(), port), - Endpoint(our_external_endpoint_->address(), port)); + our_external_endpoint_ ? Endpoint(our_external_endpoint_->address(), port) + : Endpoint()); } template @@ -536,8 +540,8 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { auto response_ptr = std::make_shared(std::move(connect_response)); LOG(kError) << " AddNode "; connection_manager_.AddNode( - NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), true), - response_ptr->receiver_endpoints(), + NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), false), + response_ptr->requester_endpoints(), [=](asio::error_code error, boost::optional added) { if (!destroy_guard.lock()) return; From 58e9e29b36365b17e3757becee0004d17bfc57c7 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Tue, 24 Mar 2015 16:17:08 +0100 Subject: [PATCH 65/72] Removes std::cerr debug output --- src/maidsafe/routing/connections.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index dea5349e..8a9b7564 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -215,8 +215,6 @@ AsyncResultReturn Connections::Connect(Endpoi Handler handler(std::forward(token)); asio::async_result result(handler); - std::cerr << "Connections::Connect(" << endpoint << ")\n"; - get_io_service().post([=]() mutable { crux::endpoint unspecified_ep; From df4dc14875d2ab1ba67b69d3767b3238eaf38c70 Mon Sep 17 00:00:00 2001 From: prakash Date: Tue, 24 Mar 2015 16:36:30 +0000 Subject: [PATCH 66/72] wip --- include/maidsafe/routing/routing_node.h | 82 ++++++++++------------ src/maidsafe/routing/connection_manager.cc | 7 -- src/maidsafe/routing/connection_manager.h | 17 ++++- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 114dc1de..ef62634c 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -121,6 +121,9 @@ class RoutingNode { template void SendToBootstrapNode(const DestinationAddress& destination, const SourceAddress& source, const MessageType& message, Authority authority); + void SendToBootstrapNode(const SerialisedMessage& serialised_message); + void SendToNonRoutingNode(const Address& destination, + const SerialisedMessage& serialised_message); bool TryCache(MessageTypeTag tag, MessageHeader header, Address name); Authority OurAuthority(const Address& element, const MessageHeader& header) const; void MessageReceived(Address peer_id, SerialisedMessage serialised_message); @@ -372,7 +375,8 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; })) { // send message to connected node - connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message); + connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message, + [](asio::error_code /*error*/) {}); return; } } @@ -466,7 +470,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h LOG(kInfo) << "HandleMessage -- Connect msg .. need to connect to " << connect.requester_id(); if (!connection_manager_.SuggestNodeToAdd(connect.requester_id())) return; - auto targets(connection_manager_.GetTarget(connect.requester_id())); + ConnectResponse respond(connect.requester_endpoints(), NextEndpointPair(), connect.requester_id(), OurId(), passport::PublicPmid(our_fob_)); assert(connect.receiver_id() == OurId()); @@ -475,39 +479,16 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h SourceAddress(OurSourceAddress()), original_header.MessageId(), Authority::node, asymm::Sign(asymm::PlainText(Serialise(respond)), our_fob_.private_key())); + auto message = Serialise(header, MessageToTag::value(), respond); + if (bootstrap_node_) { // TODO cleanup - auto message = Serialise(header, MessageToTag::value(), respond); - connection_manager_.Send(*bootstrap_node_, std::move(message), [](asio::error_code error) { - if (error) { - LOG(kWarning) << "Cannot send ConnectResponse via bootstrap node" << error.message(); - } else { - LOG(kInfo) << "Sent ConnectResponse"; - } - }); + SendToBootstrapNode(message); return; } - // FIXME(dirvine) Do we need to pass a shared_from_this type object or this may segfault on - // shutdown - // :24/01/2015 - for (auto& target : targets) { - // FIXME(Team): Do we need to serialize this for each target? - auto message = Serialise(header, MessageToTag::value(), respond); - connection_manager_.Send(target.id, std::move(message), [](asio::error_code) {}); - } - //////////////////////// temp code Delete me - - auto temp = (*original_header.ReplyToAddress()).data; - auto message = Serialise(header, MessageToTag::value(), respond); - connection_manager_.Send(temp, std::move(message), [=](asio::error_code error) { - if (error) { - LOG(kWarning) << "Could not send to " << temp; - } else { - LOG(kVerbose) << "Sent ConnectResponse to " << temp; - } - }); - // connection_manager_.SendToNonRoutingNode(temp, message); // FIXME(Prakash) - //////////////////////// + SendSwarmOrParallel(connect.requester_id(), message); + if (original_header.ReplyToAddress()) + SendToNonRoutingNode((*original_header.ReplyToAddress()).data, message); std::weak_ptr destroy_guard = destroy_indicator_; LOG(kError) << " AddNodeAccept "; @@ -575,17 +556,9 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi // if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle // message part ! - // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? temp code to get past zero - // state. Delete me !! - auto temp = (*original_header.ReplyToAddress()).data; - // LOG(kVerbose) << "FindGroupResp sent to " << temp ; - connection_manager_.Send(temp, message, [=](asio::error_code error) { - if (error) { - LOG(kWarning) << "Could not send to " << temp; - } else { - // LOG(kVerbose) << "Sent FindGroupResponse to " << temp; - } - }); + // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? + if (original_header.ReplyToAddress()) + SendToNonRoutingNode((*original_header.ReplyToAddress()).data, message); } template @@ -701,11 +674,34 @@ void RoutingNode::SendToBootstrapNode(const DestinationAddress& destinati connection_manager_.Send( *bootstrap_node_, std::move(wrapped_message), [](asio::error_code error) { if (error) { - LOG(kWarning) << "Connection manager cannot send to bootstrap node" << error.message(); + LOG(kWarning) << "Connection manager cannot send to bootstrap node, " << error.message(); } }); } +template +void RoutingNode::SendToBootstrapNode(const SerialisedMessage& serialised_message) { + auto destination = *bootstrap_node_; + connection_manager_.Send( + destination, serialised_message, [=](asio::error_code error) { + if (error) { + LOG(kWarning) << "Connection manager cannot send to bootstrap node " << destination + << " , error : " << error.message(); + } + }); +} + +template +void RoutingNode::SendToNonRoutingNode(const Address& destination, + const SerialisedMessage& serialised_message) { + connection_manager_.SendToNonRoutingNode(destination, serialised_message, + [=](asio::error_code error) { + if (error) { + LOG(kWarning) << "Connection manager cannot send to destination " << destination + << " , error : " << error.message(); + } + }); +} } // namespace routing diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 69080162..dd990185 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -236,13 +236,6 @@ void ConnectionManager::StartReceiving() { }); } -void ConnectionManager::SendToNonRoutingNode(const Address& /*addr*/, - const SerialisedMessage& /*message*/) { - // connections_->Send(addr, message, std::move(handler)); // FIXME(Prakash) - // remove connection if failed -} - - void ConnectionManager::HandleConnectionLost(Address lost_connection) { routing_table_.DropNode(lost_connection); connected_non_routing_nodes_.erase(lost_connection); diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index b41c91b8..a558cc30 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -124,8 +124,8 @@ class ConnectionManager { template void Send(const Address&, const SerialisedMessage&, Handler); - void SendToNonRoutingNode(const Address&, - const SerialisedMessage&); // remove connection if fails + template + void SendToNonRoutingNode(const Address&, const SerialisedMessage&, Handler); unsigned short AcceptingPort() const { return our_accept_port_; } @@ -174,6 +174,19 @@ void ConnectionManager::Send(const Address& addr, const SerialisedMessage& messa }); } +template +void ConnectionManager::SendToNonRoutingNode(const Address& addr, + const SerialisedMessage& message, + Handler handler) { + auto found = connected_non_routing_nodes_.find(addr); + if (found != connected_non_routing_nodes_.end()) { + Send(addr, message, handler); + } else { + handler(make_error_code(RoutingErrors::not_connected)); + } +} + + template void ConnectionManager::Connect(asio::ip::udp::endpoint remote_endpoint, Handler handler) { connections_->Connect(remote_endpoint, From 86691d55b9b24eb83ebcce2d2dc7800d9a5808a3 Mon Sep 17 00:00:00 2001 From: prakash Date: Tue, 24 Mar 2015 17:47:41 +0000 Subject: [PATCH 67/72] minor update and fix from peter --- include/maidsafe/routing/routing_node.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index f088fe20..d743c7a2 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -521,7 +521,7 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { auto response_ptr = std::make_shared(std::move(connect_response)); LOG(kError) << " AddNode "; connection_manager_.AddNode( - NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), false), + NodeInfo(response_ptr->receiver_id(), response_ptr->receiver_fob(), false), response_ptr->requester_endpoints(), [=](asio::error_code error, boost::optional added) { if (!destroy_guard.lock()) @@ -554,15 +554,12 @@ void RoutingNode::HandleMessage(FindGroup find_group, MessageHeader origi original_header.MessageId(), Authority::nae_manager, asymm::Sign(asymm::PlainText(Serialise(response)), our_fob_.private_key())); auto message(Serialise(header, MessageToTag::value(), response)); - for (const auto& node : connection_manager_.GetTarget(original_header.FromNode())) { - connection_manager_.Send(node.id, message, [](asio::error_code) {}); + if (bootstrap_node_) { + SendToBootstrapNode(message); + } else { + SendSwarmOrParallel(original_header.FromNode(), message); } - // if node in my group && in non routing list send it to non_routnig list as well - // if (connection_manager_.AddressInCloseGroupRange()) this check is already happeing in Handle - // message part ! - - // FIXME (Prakash) Need to send to bootstrap node id rt is empty ? if (original_header.ReplyToAddress()) SendToNonRoutingNode((*original_header.ReplyToAddress()).data, message); } From 7d38d75a50e511db6d5ebf65106def146a104c88 Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Wed, 25 Mar 2015 01:44:28 +0100 Subject: [PATCH 68/72] Connections class to report already_connected error When connection already there. --- include/maidsafe/routing/routing_node.h | 24 +++--- src/maidsafe/routing/connection_manager.cc | 26 ++++++- src/maidsafe/routing/connections.h | 88 +++++++++++----------- 3 files changed, 79 insertions(+), 59 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index ddfc0283..376e537c 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -198,7 +198,7 @@ void RoutingNode::StartBootstrap() { // (hardcoded endpoints).on failure keep retrying all options forever return; } - LOG(kInfo) << "Bootstrapped with " << peer_addr; + LOG(kInfo) << OurId() << " Bootstrapped with " << peer_addr << " his ep:" << live_port_ep; // FIXME(Team): Thread safety. bootstrap_node_ = peer_addr; our_external_endpoint_ = our_public_endpoint; @@ -263,6 +263,7 @@ PutReturn RoutingNode::Put(std::shared_ptr data, CompletionToken&& token) { PutHandler handler(std::forward(token)); asio::async_result result(handler); + asio::post(asio_service_.service(), [=]() mutable { MessageHeader our_header( std::make_pair(Destination(OurId()), boost::none), // send to ClientMgr @@ -319,7 +320,7 @@ void RoutingNode::ConnectToCloseGroup() { template -void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { +void RoutingNode::MessageReceived(Address /*peer_id*/, SerialisedMessage serialised_message) { InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; @@ -329,10 +330,10 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri LOG(kError) << "header failure." << boost::current_exception_diagnostic_information(); return; } - LOG(kVerbose) << OurId() - << " Msg from " << peer_id - << " tag:" << static_cast::type>(tag) - << " " << header; + //LOG(kVerbose) << OurId() + // << " Msg from " << peer_id + // << " tag:" << static_cast::type>(tag) + // << " " << header; if (filter_.Check(header.FilterValue())) return; // already seen @@ -516,11 +517,12 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h //////////////////////// std::weak_ptr destroy_guard = destroy_indicator_; - LOG(kError) << " AddNodeAccept "; + LOG(kError) << OurId() << " calling AddNodeAccept " << connect.requester_id(); connection_manager_.AddNodeAccept( NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints(), [=](asio::error_code error, boost::optional added) { + LOG(kError) << " AddNodeAccept "; if (!destroy_guard.lock()) return; if (!error && added) @@ -538,10 +540,10 @@ void RoutingNode::HandleMessage(ConnectResponse connect_response) { // Workaround because ConnectResponse isn't copyconstructibe. auto response_ptr = std::make_shared(std::move(connect_response)); - LOG(kError) << " AddNode "; + LOG(kError) << OurId() << " calling AddNode " << response_ptr->receiver_id() << " " << response_ptr->receiver_endpoints(); connection_manager_.AddNode( - NodeInfo(response_ptr->requester_id(), response_ptr->receiver_fob(), false), - response_ptr->requester_endpoints(), + NodeInfo(response_ptr->receiver_id(), response_ptr->receiver_fob(), false), + response_ptr->receiver_endpoints(), [=](asio::error_code error, boost::optional added) { if (!destroy_guard.lock()) return; @@ -634,8 +636,6 @@ void RoutingNode::HandleMessage(GetData get_data, MessageHeader header) { template void RoutingNode::HandleMessage(PutData put_data, MessageHeader original_header) { - LOG(kVerbose) << "Handling PutData: " << put_data.type_id() << " " - << hex::Substr(put_data.data()) << " " << put_data.data().size(); std::shared_ptr parsed(Parse>(put_data.data())); cache_.Add(parsed->NameAndType(), put_data.data()); auto result = static_cast(this) diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index fdeec390..14e4b8d2 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -101,6 +101,7 @@ void ConnectionManager::StartAccepting() { auto expected_i = expected_accepts_.find(result.his_address); if (expected_i != expected_accepts_.end()) { + LOG(kInfo) << OurId() << " StartAccepting handler 1 " << error.message() << "\n"; auto expected = std::move(expected_i->second); expected_accepts_.erase(expected_i); @@ -111,6 +112,10 @@ void ConnectionManager::StartAccepting() { return; } } else { + LOG(kInfo) << OurId() << " StartAccepting handler 2 " << error.message() << " his_id:" << result.his_address << "\n"; + for (const auto& a : expected_accepts_) { + LOG(kInfo) << "--- " << a.first << "\n"; + } if (!error) { connected_non_routing_nodes_.insert(result.his_address); } @@ -126,6 +131,13 @@ void ConnectionManager::StartAccepting() { void ConnectionManager::HandleAddNode(asio::error_code error, NodeInfo node_info, OnAddNode user_handler) { + LOG(kInfo) << OurId() << " HandleAddNode " << error.message(); + + if (error == asio::error::already_connected) { + connected_non_routing_nodes_.erase(node_info.id); + error = asio::error_code(); + } + if (error && error != asio::error::timed_out) { return; } @@ -138,6 +150,7 @@ void ConnectionManager::HandleAddNode(asio::error_code error, NodeInfo node_info void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, OnAddNode on_node_added) { auto id = node_info.id; + LOG(kInfo) << OurId() << " AddNodeAccept " << node_info.id << "\n"; auto timer = std::make_shared(io_service_); auto canceling_handler = @@ -166,14 +179,21 @@ void ConnectionManager::AddNode(NodeInfo node_to_add, EndpointPair their_endpoin OnAddNode on_node_added) { std::weak_ptr weak_connections = connections_; - // TODO(PeterJ): Use local endpoint as well - connections_->Connect(their_endpoint_pair.external, + // TODO(PeterJ): Use both endpoints + asio::ip::udp::endpoint endpoint = their_endpoint_pair.external.address().is_unspecified() + ? their_endpoint_pair.local + : their_endpoint_pair.external; + + LOG(kInfo) << "ConnectionManager::Connect " << node_to_add.id << " " << their_endpoint_pair << "\n"; + connections_->Connect(endpoint, [=](asio::error_code error, Connections::ConnectResult result) { if (!weak_connections.lock()) { return on_node_added(asio::error::operation_aborted, boost::none); } - if (!error && (result.his_address != node_to_add.id)) { + LOG(kInfo) << OurId() << " his_address:" << result.his_address << " node_to_add:" << node_to_add.id; + if ((!error || error == asio::error::already_connected) + && (result.his_address != node_to_add.id)) { error = asio::error::fault; } diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 8a9b7564..559b40a2 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -114,9 +114,8 @@ class Connections { std::function on_drop_; std::map> acceptors_; // NOLINT - std::map> connections_; - std::map id_to_endpoint_map_; - + std::map> connections_; + std::map> connecting_sockets_; struct ReceiveInput { asio::error_code error; @@ -142,17 +141,13 @@ AsyncResultReturn Connections::Send(const Address& remote_id, const Seria asio::async_result result(handler); get_io_service().post([=]() mutable { - auto remote_endpoint_i = id_to_endpoint_map_.find(remote_id); + auto socket_i = connections_.find(remote_id); - if (remote_endpoint_i == id_to_endpoint_map_.end()) { + if (socket_i == connections_.end()) { LOG(kWarning) << "bad_descriptor !! " << remote_id; return post(handler, asio::error::bad_descriptor); } - auto remote_endpoint = remote_endpoint_i->second; - auto socket_i = connections_.find(remote_endpoint); - assert(socket_i != connections_.end()); - auto& socket = socket_i->second; auto buffer = std::make_shared(std::move(bytes)); @@ -165,8 +160,7 @@ AsyncResultReturn Connections::Send(const Address& remote_id, const Seria return post(handler, asio::error::operation_aborted); } if (error) { - id_to_endpoint_map_.erase(remote_id); - connections_.erase(remote_endpoint); + connections_.erase(remote_id); } post(handler, convert::ToStd(error)); }); @@ -218,18 +212,18 @@ AsyncResultReturn Connections::Connect(Endpoi get_io_service().post([=]() mutable { crux::endpoint unspecified_ep; + LOG(kInfo) << OurId() << " Connections::Connect(" << endpoint << ")\n"; if (endpoint.address().is_v4()) unspecified_ep = crux::endpoint(boost::asio::ip::udp::v4(), 0); else unspecified_ep = crux::endpoint(boost::asio::ip::udp::v6(), 0); auto socket = std::make_shared(get_io_service(), unspecified_ep); + auto local_endpoint = socket->local_endpoint(); - auto insert_result = connections_.insert(std::make_pair(convert::ToBoost(endpoint), socket)); + auto insert_result = connecting_sockets_.insert(std::make_pair(local_endpoint, socket)); - if (!insert_result.second) { - return post(handler, asio::error::already_started, ConnectResult()); - } + assert(insert_result.second); std::weak_ptr weak_socket = socket; @@ -239,16 +233,15 @@ AsyncResultReturn Connections::Connect(Endpoi if (!socket) { return post(handler, asio::error::operation_aborted, ConnectResult()); } + if (error) { + connecting_sockets_.erase(local_endpoint); return post(handler, convert::ToStd(error), ConnectResult()); } auto remote_endpoint = socket->remote_endpoint(); - connections_[remote_endpoint] = socket; - auto his_endpoint = convert::ToAsio(socket->remote_endpoint()); - - AsyncExchange(*socket, Serialise(our_id_, his_endpoint), + AsyncExchange(*socket, Serialise(our_id_, convert::ToAsio(remote_endpoint)), [=](boost::system::error_code error, SerialisedMessage data) mutable { auto socket = weak_socket.lock(); @@ -256,8 +249,9 @@ AsyncResultReturn Connections::Connect(Endpoi return post(handler, asio::error::operation_aborted, ConnectResult()); } + connecting_sockets_.erase(local_endpoint); + if (error) { - connections_.erase(remote_endpoint); return post(handler, convert::ToStd(error), ConnectResult()); } @@ -265,7 +259,13 @@ AsyncResultReturn Connections::Connect(Endpoi Address his_id; asio::ip::udp::endpoint our_endpoint; Parse(stream, his_id, our_endpoint); - id_to_endpoint_map_[his_id] = remote_endpoint; + + auto result = connections_.insert(std::make_pair(his_id, socket)); + + if (!result.second) { + return post(handler, asio::error::already_connected, ConnectResult{his_id, our_endpoint}); + } + StartReceiving(his_id, remote_endpoint, socket); post(handler, convert::ToStd(error), ConnectResult{his_id, our_endpoint}); @@ -284,10 +284,8 @@ AsyncResultReturn Connections::Accept(Port por Handler handler(std::forward(token)); asio::async_result result(handler); - auto loopback = [](Port port) { return crux::endpoint(boost::asio::ip::udp::v4(), port); }; - // TODO(PeterJ) Make sure this operation is thread safe in crux. std::shared_ptr acceptor; try { @@ -321,14 +319,16 @@ AsyncResultReturn Connections::Accept(Port por } acceptors_.erase(port); + auto remote_endpoint = socket->remote_endpoint(); - connections_[remote_endpoint] = socket; - auto his_endpoint = convert::ToAsio(socket->remote_endpoint()); + auto local_endpoint = socket->local_endpoint(); + + connecting_sockets_[local_endpoint] = socket; std::weak_ptr weak_socket = socket; - AsyncExchange(*socket, Serialise(our_id_, his_endpoint), [=](boost::system::error_code error, - SerialisedMessage data) mutable { + AsyncExchange(*socket, Serialise(our_id_, convert::ToAsio(remote_endpoint)), + [=](boost::system::error_code error, SerialisedMessage data) mutable { auto socket = weak_socket.lock(); if (!socket) { @@ -337,7 +337,7 @@ AsyncResultReturn Connections::Accept(Port por } if (error) { - connections_.erase(remote_endpoint); + connecting_sockets_.erase(local_endpoint); return post(handler, convert::ToStd(error), AcceptResult{convert::ToAsio(remote_endpoint), Address(), Endpoint()}); } @@ -347,11 +347,20 @@ AsyncResultReturn Connections::Accept(Port por Endpoint our_endpoint; Parse(stream, his_id, our_endpoint); - id_to_endpoint_map_[his_id] = remote_endpoint; + auto result = connections_.insert(std::make_pair(his_id, socket)); + StartReceiving(his_id, remote_endpoint, socket); - post(handler, convert::ToStd(error), - AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); + if (result.second) { + // Inserted + post(handler, convert::ToStd(error), + AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); + } + else { + remote_endpoint = result.first->second->remote_endpoint(); + post(handler, asio::error::already_connected, + AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); + } }); }); }); @@ -375,8 +384,8 @@ inline void Connections::StartReceiving(const Address& id, const crux::endpoint& } if (error) { - id_to_endpoint_map_.erase(id); - connections_.erase(remote_endpoint); + connections_.erase(id); + size = 0; } buffer->resize(size); @@ -396,7 +405,7 @@ inline void Connections::Shutdown() { work_.reset(); acceptors_.clear(); connections_.clear(); - id_to_endpoint_map_.clear(); + connecting_sockets_.clear(); }); } @@ -410,16 +419,7 @@ void Connections::post(Handler&& handler, Args&&... args) { inline void Connections::Drop(const Address& their_id) { get_io_service().post([=]() { - // TODO(Team): Might it be that it is in connections_ but not in the id_to_endpoint_map_? - // I.e. that above layers would wan't to remove by ID nodes which were not - // yet connected? - auto i = id_to_endpoint_map_.find(their_id); - - if (i == id_to_endpoint_map_.end()) { - return; - } - - connections_.erase(i->second); + connections_.erase(their_id); }); } From 43886dc9f4a12b5170a9290408caf11cb35ec23e Mon Sep 17 00:00:00 2001 From: prakash Date: Wed, 25 Mar 2015 01:28:55 +0000 Subject: [PATCH 69/72] added log --- src/maidsafe/routing/routing_table.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/maidsafe/routing/routing_table.cc b/src/maidsafe/routing/routing_table.cc index b7d70144..e7cc7f57 100644 --- a/src/maidsafe/routing/routing_table.cc +++ b/src/maidsafe/routing/routing_table.cc @@ -202,6 +202,8 @@ bool RoutingTable::NewNodeIsBetterThanExisting( void RoutingTable::PushBackThenSort(NodeInfo their_info) { nodes_.push_back(std::move(their_info)); + LOG(kSuccess) << " RT [ "<< our_id_ << " ] addedd [ " << nodes_.back().id << " ] , size : " + << nodes_.size(); std::sort(std::begin(nodes_), std::end(nodes_), comparison_); } From 46856552d665ec4af717ec7a96fe5d255477f728 Mon Sep 17 00:00:00 2001 From: prakash Date: Wed, 25 Mar 2015 17:23:00 +0000 Subject: [PATCH 70/72] wip on relay logic --- include/maidsafe/routing/routing_node.h | 43 +++++++++++++--- src/maidsafe/routing/connections.h | 3 +- .../tests/routing_fake_vault_facade_test.cc | 51 ++++++++++--------- 3 files changed, 62 insertions(+), 35 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 16e7f348..1ad015c6 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -376,18 +376,43 @@ void RoutingNode::MessageReceived(Address /*peer_id*/, SerialisedMessage // TODO(Prakash) cleanup aim to abstract relay logic here and may be use term routed message for // response messages - if (header.RelayedMessage() && (header.FromNode().data != OurId())) { // skip outgoing msgs + + bool relay_request = (header.Source().reply_to_address && + (header.Source().node_address.data == OurId()) && + (header.Destination().first.data != OurId())); + if (relay_request) { // relay request + LOG(kVerbose) << "relay request already fwded"; +// return; // already fwded // Can not return here. THis could be a group message and I might be group member + } + + bool relay_response = (header.Destination().second && + (header.Destination().first.data == OurId())); + + if (relay_response) { // relay response + LOG(kVerbose) << OurId() << " relay response try to send to nrt " << (*header.ReplyToAddress()).data; std::set
connected_non_routing_nodes{connection_manager_.GetNonRoutingNodes()}; - if (std::any_of( - std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), - [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; })) { - // send message to connected node - connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message, - [](asio::error_code /*error*/) {}); - return; + if (std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), + [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; + })) { + // send message to connected node + connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message, + [](asio::error_code /*error*/) {}); } + return; // no point progressing further as I was destination and I don't have the replyto node connected } +// if (header.RelayedMessage() && (hjeader.FromNode().data != OurId())) { // skip outgoing msgs +// std::set
connected_non_routing_nodes{connection_manager_.GetNonRoutingNodes()}; +// if (std::any_of( +// std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), +// [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; })) { +// // send message to connected node +// connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message, +// [](asio::error_code /*error*/) {}); +// return; +// } +// } + if (!connection_manager_.AddressInCloseGroupRange(header.Destination().first)) { LOG(kVerbose) << "not for us"; return; // not for us @@ -398,6 +423,8 @@ void RoutingNode::MessageReceived(Address /*peer_id*/, SerialisedMessage if ((tag == MessageTypeTag::Connect) || (tag == MessageTypeTag::ConnectResponse)) { if (header.Destination().first.data != OurId()) { // not for me + if ((!header.Destination().second.is_initialized())) + return; if ((header.Destination().second) && (*header.Destination().second).data != OurId()) { LOG(kVerbose) << "not for me"; return; diff --git a/src/maidsafe/routing/connections.h b/src/maidsafe/routing/connections.h index 559b40a2..b69773dd 100644 --- a/src/maidsafe/routing/connections.h +++ b/src/maidsafe/routing/connections.h @@ -349,10 +349,9 @@ AsyncResultReturn Connections::Accept(Port por auto result = connections_.insert(std::make_pair(his_id, socket)); - StartReceiving(his_id, remote_endpoint, socket); - if (result.second) { // Inserted + StartReceiving(his_id, remote_endpoint, socket); post(handler, convert::ToStd(error), AcceptResult{convert::ToAsio(remote_endpoint), his_id, our_endpoint}); } diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index ddf48699..87273c54 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -33,31 +33,32 @@ namespace test { TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { vault::test::FakeVaultFacade vault1; vault::test::FakeVaultFacade vault2; - Sleep(std::chrono::seconds(5)); - - LOG(kInfo) << "================================================================================="; - - std::shared_ptr immutable_data( - new ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50)))); - std::future put_future(vault2.Put(immutable_data, asio::use_future)); - EXPECT_NO_THROW(put_future.get()); - passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); - std::shared_ptr public_maid(new passport::PublicMaid(maid_and_signer.first)); - put_future = vault2.Put(public_maid, asio::use_future); - EXPECT_NO_THROW(put_future.get()); - - - AsioService asio_service(1); - asio::spawn(asio_service.service(), [&](asio::yield_context yield) { - std::error_code error; - vault2.Put(immutable_data, yield[error]); - EXPECT_FALSE(error) << error.message(); - vault2.Put(public_maid, yield[error]); - EXPECT_FALSE(error) << error.message(); - }); - - Sleep(std::chrono::seconds(5)); - asio_service.Stop(); + Sleep(std::chrono::seconds(15)); + vault::test::FakeVaultFacade vault3; + Sleep(std::chrono::seconds(15)); +// LOG(kInfo) << "================================================================================="; + +// std::shared_ptr immutable_data( +// new ImmutableData(NonEmptyString(RandomAlphaNumericBytes(1, 50)))); +// std::future put_future(vault2.Put(immutable_data, asio::use_future)); +// EXPECT_NO_THROW(put_future.get()); +// passport::MaidAndSigner maid_and_signer(passport::CreateMaidAndSigner()); +// std::shared_ptr public_maid(new passport::PublicMaid(maid_and_signer.first)); +// put_future = vault2.Put(public_maid, asio::use_future); +// EXPECT_NO_THROW(put_future.get()); + + +// AsioService asio_service(1); +// asio::spawn(asio_service.service(), [&](asio::yield_context yield) { +// std::error_code error; +// vault2.Put(immutable_data, yield[error]); +// EXPECT_FALSE(error) << error.message(); +// vault2.Put(public_maid, yield[error]); +// EXPECT_FALSE(error) << error.message(); +// }); + +// Sleep(std::chrono::seconds(5)); +// asio_service.Stop(); } // TEST(RoutingFakeVaultFacadeTest, FUNC_PutGet) { From 0866857720296b667bfdcb3f49aa3d18016e07ad Mon Sep 17 00:00:00 2001 From: prakash Date: Thu, 26 Mar 2015 11:30:12 +0000 Subject: [PATCH 71/72] added debug code --- include/maidsafe/routing/routing_node.h | 18 ++++++++++++------ src/maidsafe/routing/message_header.h | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 1ad015c6..3caeaf46 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -207,7 +207,7 @@ void RoutingNode::StartBootstrap() { our_external_endpoint_ = our_public_endpoint; // bootstrap_endpoint_ = our_endpoint; this will not required if // connection manager has this connection - PutOurPublicPmid(); +// PutOurPublicPmid(); // DISABLED FOR TESTING UNCOMMENT ConnectToCloseGroup(); }); @@ -323,7 +323,7 @@ void RoutingNode::ConnectToCloseGroup() { template -void RoutingNode::MessageReceived(Address /*peer_id*/, SerialisedMessage serialised_message) { +void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage serialised_message) { InputVectorStream binary_input_stream{serialised_message}; MessageHeader header; MessageTypeTag tag; @@ -333,16 +333,17 @@ void RoutingNode::MessageReceived(Address /*peer_id*/, SerialisedMessage LOG(kError) << "header failure." << boost::current_exception_diagnostic_information(); return; } - //LOG(kVerbose) << OurId() - // << " Msg from " << peer_id - // << " tag:" << static_cast::type>(tag) - // << " " << header; if (filter_.Check(header.FilterValue())) return; // already seen // add to filter as soon as posible filter_.Add({header.FilterValue()}); + LOG(kVerbose) << OurId() + << " Msg from peer " << peer_id + << " tag:" << static_cast::type>(tag) + << " " << header; + // We add these to cache if (tag == MessageTypeTag::GetDataResponse) { auto data = Parse(binary_input_stream); @@ -602,6 +603,11 @@ void RoutingNode::HandleMessage(FindGroupResponse find_group_response, LOG(kInfo) << OurId() << " HandleMessage " << find_group_response; for (const auto node_pmid : find_group_response.group()) { Address node_id(node_pmid.Name()); + //DELETE ME DEBUG CODE + if ((find_group_response.group().size() == 2) &&(node_id == *bootstrap_node_)) { + LOG(kWarning) << "skipping bootstrap guy to connect"; + continue; + } if (!connection_manager_.SuggestNodeToAdd(node_id)) continue; Connect connect_message(NextEndpointPair(), OurId(), node_id, passport::PublicPmid(our_fob_)); diff --git a/src/maidsafe/routing/message_header.h b/src/maidsafe/routing/message_header.h index bbe5106d..a6a73377 100644 --- a/src/maidsafe/routing/message_header.h +++ b/src/maidsafe/routing/message_header.h @@ -175,8 +175,8 @@ class MessageHeader { inline std::ostream& operator<<(std::ostream& os, const MessageHeader& hdr) { - return os << "(Header src:" << hdr.Source() - << ", dst:("; + os << "(Header src:" << hdr.Source() + << ", dst:("; auto dst = hdr.Destination(); From a514a93e1fe241be1e8dc6fa39c3baa51f256c8a Mon Sep 17 00:00:00 2001 From: Peter Jankuliak Date: Thu, 26 Mar 2015 13:35:48 +0100 Subject: [PATCH 72/72] Debug output --- include/maidsafe/routing/routing_node.h | 9 ++++--- src/maidsafe/routing/connection_manager.cc | 2 +- src/maidsafe/routing/connection_manager.h | 2 +- src/maidsafe/routing/message_header.h | 25 ++++++++++++++++--- src/maidsafe/routing/messages/connect.h | 4 +-- .../tests/routing_fake_vault_facade_test.cc | 5 +++- 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/include/maidsafe/routing/routing_node.h b/include/maidsafe/routing/routing_node.h index 3caeaf46..bc9f1518 100644 --- a/include/maidsafe/routing/routing_node.h +++ b/include/maidsafe/routing/routing_node.h @@ -174,7 +174,7 @@ RoutingNode::RoutingNode() sentinel_([](Address) {}, [](GroupAddress) {}), cache_(std::chrono::minutes(60)), destroy_indicator_(new boost::none_t) { - LOG(kInfo) << "RoutingNode < " << OurId() << " >"; + LOG(kInfo) << OurId() << " RoutingNode created"; // store this to allow other nodes to get our ID on startup. IF they have full routing tables they // need Quorum number of these signed anyway. passport::PublicPmid our_public_pmid(our_fob_); @@ -390,10 +390,10 @@ void RoutingNode::MessageReceived(Address peer_id, SerialisedMessage seri (header.Destination().first.data == OurId())); if (relay_response) { // relay response - LOG(kVerbose) << OurId() << " relay response try to send to nrt " << (*header.ReplyToAddress()).data; + //LOG(kVerbose) << OurId() << " relay response try to send to nrt " << (*header.ReplyToAddress()).data; std::set
connected_non_routing_nodes{connection_manager_.GetNonRoutingNodes()}; if (std::any_of(std::begin(connected_non_routing_nodes), std::end(connected_non_routing_nodes), - [&header](const Address& node) { return node == (*header.ReplyToAddress()).data; + [&header](const Address& node) { return node == header.ReplyToAddress()->data; })) { // send message to connected node connection_manager_.SendToNonRoutingNode(*header.ReplyToAddress(), serialised_message, @@ -508,6 +508,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h ConnectResponse respond(connect.requester_endpoints(), NextEndpointPair(), connect.requester_id(), OurId(), passport::PublicPmid(our_fob_)); + assert(connect.receiver_id() == OurId()); MessageHeader header(DestinationAddress(original_header.ReturnDestinationAddress()), @@ -526,7 +527,7 @@ void RoutingNode::HandleMessage(Connect connect, MessageHeader original_h SendToNonRoutingNode((*original_header.ReplyToAddress()).data, message); std::weak_ptr destroy_guard = destroy_indicator_; - LOG(kError) << OurId() << " calling AddNodeAccept " << connect.requester_id(); + connection_manager_.AddNodeAccept( NodeInfo(connect.requester_id(), connect.requester_fob(), true), connect.requester_endpoints(), diff --git a/src/maidsafe/routing/connection_manager.cc b/src/maidsafe/routing/connection_manager.cc index 9a56af45..9234beb6 100644 --- a/src/maidsafe/routing/connection_manager.cc +++ b/src/maidsafe/routing/connection_manager.cc @@ -169,7 +169,7 @@ void ConnectionManager::AddNodeAccept(NodeInfo node_info, EndpointPair, OnAddNod // TODO(Team): Is the timeout value correct? Should it be in defined // somewhere else? - timer->async_wait(std::chrono::seconds(10), [=]() { + timer->async_wait(std::chrono::seconds(2), [=]() { expected_accepts_.erase(id); HandleAddNode(asio::error::timed_out, node_info, on_node_added); }); diff --git a/src/maidsafe/routing/connection_manager.h b/src/maidsafe/routing/connection_manager.h index eb2945dd..6731cea5 100644 --- a/src/maidsafe/routing/connection_manager.h +++ b/src/maidsafe/routing/connection_manager.h @@ -161,7 +161,7 @@ template void ConnectionManager::Send(const Address& addr, const SerialisedMessage& message, Handler handler) { std::weak_ptr guard = connections_; - LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); + //LOG(kVerbose) << OurId() << " Send to node " << addr << ", msg : " << hex::Substr(message); connections_->Send(addr, message, [=](asio::error_code error) mutable { handler(error); diff --git a/src/maidsafe/routing/message_header.h b/src/maidsafe/routing/message_header.h index a6a73377..1c417bbb 100644 --- a/src/maidsafe/routing/message_header.h +++ b/src/maidsafe/routing/message_header.h @@ -117,11 +117,30 @@ class MessageHeader { NodeAddress FromNode() const { return source_.node_address; } boost::optional FromGroup() const { return source_.group_address; } Authority FromAuthority() { return authority_; } + bool RelayedMessage() const { - return (static_cast(source_.reply_to_address) || - static_cast(destination_.second)); } + return static_cast(source_.reply_to_address) || + static_cast(destination_.second); + } + + boost::optional
RelayedTo() const { + if (source_.reply_to_address) { + return static_cast(*source_.reply_to_address); + } + else if (destination_.second) { + return static_cast(*destination_.second); + } + return boost::none; + } + boost::optional ReplyToAddress() const { - return source_.reply_to_address; + if (source_.reply_to_address) { + return source_.reply_to_address; + } + if (destination_.second) { + return destination_.second; + } + return boost::none; } Address FromAddress() const { diff --git a/src/maidsafe/routing/messages/connect.h b/src/maidsafe/routing/messages/connect.h index 96e0645a..fc45a196 100644 --- a/src/maidsafe/routing/messages/connect.h +++ b/src/maidsafe/routing/messages/connect.h @@ -76,8 +76,8 @@ class Connect { }; inline std::ostream& operator<<(std::ostream& os, const Connect& msg) { - return os << "(Connect " << msg.requester_endpoints() << ", " - << msg.requester_id() << ", " << msg.receiver_id() << ", ...)"; + return os << "(Connect " << msg.requester_endpoints() << ", rq:" + << msg.requester_id() << ", rc:" << msg.receiver_id() << ", (FOB...))"; } } // namespace routing diff --git a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc index 87273c54..258bb940 100644 --- a/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc +++ b/src/maidsafe/routing/tests/routing_fake_vault_facade_test.cc @@ -33,9 +33,12 @@ namespace test { TEST(RoutingFakeVaultFacadeTest, FUNC_Constructor) { vault::test::FakeVaultFacade vault1; vault::test::FakeVaultFacade vault2; - Sleep(std::chrono::seconds(15)); + Sleep(std::chrono::seconds(5)); + LOG(kInfo) << "================================================================================="; vault::test::FakeVaultFacade vault3; Sleep(std::chrono::seconds(15)); + LOG(kInfo) << "================================================================================="; + // LOG(kInfo) << "================================================================================="; // std::shared_ptr immutable_data(