From 85d25eebd38bb278ad598a291a007938854945a4 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Wed, 28 Sep 2016 10:55:58 +0200 Subject: Made changes so we can have a 1 Node cmix network. --- libcmix-network/CMakeLists.txt | 2 ++ libcmix-network/acceptor.cpp | 1 - libcmix-network/client.cpp | 5 +++- libcmix-network/client.hpp | 4 ++- libcmix-network/connect.cpp | 38 +++++++++++++++++++++++---- libcmix-network/connect.hpp | 3 ++- libcmix-network/uriparser.cpp | 3 +++ libcmix-network/uriparser.hpp | 59 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 libcmix-network/uriparser.cpp create mode 100644 libcmix-network/uriparser.hpp (limited to 'libcmix-network') diff --git a/libcmix-network/CMakeLists.txt b/libcmix-network/CMakeLists.txt index 6986eea..2574e82 100644 --- a/libcmix-network/CMakeLists.txt +++ b/libcmix-network/CMakeLists.txt @@ -7,6 +7,7 @@ add_library(cmix-network server.hpp server.cpp client.hpp client.cpp nodeclient.hpp nodeclient.cpp + uriparser.hpp uriparser.cpp ) target_compile_options(cmix-network @@ -22,6 +23,7 @@ target_link_libraries(cmix-network PUBLIC Boost::system PUBLIC ${CMAKE_THREAD_LIBS_INIT} PRIVATE cmix + PRIVATE log ) if(WIN32) diff --git a/libcmix-network/acceptor.cpp b/libcmix-network/acceptor.cpp index 34b5f0e..69b2807 100644 --- a/libcmix-network/acceptor.cpp +++ b/libcmix-network/acceptor.cpp @@ -22,7 +22,6 @@ void accept_connection(tcp::acceptor& acceptor, std::shared_ptr soc ss << ec; throw std::runtime_error(ss.str()); } - } void accept_loop(tcp::acceptor& acceptor, std::function f) diff --git a/libcmix-network/client.cpp b/libcmix-network/client.cpp index 544dd87..ce9fd4d 100644 --- a/libcmix-network/client.cpp +++ b/libcmix-network/client.cpp @@ -1,5 +1,7 @@ #include "client.hpp" +#include "logging.hpp" + #include #include @@ -19,10 +21,11 @@ void Client::handle_receive(MessageHandler message_handler, const error_code &ec buffer.commit(read_bytes); std::istream is(&buffer); + BOOST_LOG_TRIVIAL(trace) << "handling receive"; + if(!ec) { std::vector data(std::istream_iterator(is), {}); message_handler(data); - receive(message_handler); } else { if(done) { done(); diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp index 2b6a6df..46b989d 100644 --- a/libcmix-network/client.hpp +++ b/libcmix-network/client.hpp @@ -10,8 +10,10 @@ public: typedef std::function OnDoneFT; typedef std::function)> MessageHandler; -private: +protected: boost::asio::ip::tcp::socket socket; + +private: boost::asio::streambuf buffer; OnDoneFT done; diff --git a/libcmix-network/connect.cpp b/libcmix-network/connect.cpp index 679748e..bf200d5 100644 --- a/libcmix-network/connect.cpp +++ b/libcmix-network/connect.cpp @@ -1,23 +1,24 @@ #include "connect.hpp" +#include "logging.hpp" + #include +#include using namespace boost::asio::ip; using boost::asio::io_service; -boost::asio::ip::tcp::socket connect(std::string host, std::string port, io_service& io_service) { +boost::asio::ip::tcp::socket connect(std::string host, io_service& io_service) { boost::asio::ip::basic_resolver resolver(io_service); - boost::asio::ip::basic_resolver_query query(host, port); - boost::asio::ip::basic_endpoint endpoint; + boost::asio::ip::basic_resolver_query query(host, ""); for(auto it = resolver.resolve(query); it != boost::asio::ip::tcp::resolver::iterator(); ++it) { - endpoint = *it; boost::system::error_code ec; boost::asio::ip::tcp::socket socket(io_service); - socket.connect(endpoint, ec); + socket.connect(*it, ec); if(ec) { continue; } else { @@ -27,3 +28,30 @@ boost::asio::ip::tcp::socket connect(std::string host, std::string port, io_serv throw std::runtime_error("None of the supplied endpoints responded"); } + +void async_connect_iteration(tcp::socket& socket, boost::asio::ip::tcp::resolver::iterator it, std::function on_connect) { + if(it == boost::asio::ip::tcp::resolver::iterator()) { + throw std::runtime_error("None of the supplied endpoints responded"); + } + + auto handler = [&socket, it, on_connect](boost::system::error_code const& ec) { + if(ec) { + BOOST_LOG_TRIVIAL(info) << ec << std::endl; + async_connect_iteration(socket, std::next(it), on_connect); + } else { + on_connect(); + } + }; + + socket.async_connect(*it, handler); +} + +void async_connect(tcp::socket& socket, std::string host, std::string next_port, std::function on_connect) +{ + boost::asio::ip::basic_resolver resolver(socket.get_io_service()); + boost::asio::ip::basic_resolver_query query(host, next_port); + + auto it = resolver.resolve(query); + + async_connect_iteration(socket, it, on_connect); +} diff --git a/libcmix-network/connect.hpp b/libcmix-network/connect.hpp index 7f5b5c3..071ed9b 100644 --- a/libcmix-network/connect.hpp +++ b/libcmix-network/connect.hpp @@ -3,4 +3,5 @@ #include #include -boost::asio::ip::tcp::socket connect(std::string host, std::string port, boost::asio::io_service& io_service); +boost::asio::ip::tcp::socket connect(std::string host, boost::asio::io_service& io_service); +void async_connect(boost::asio::ip::tcp::socket& socket, std::string host, std::string next_port, std::function on_connect); diff --git a/libcmix-network/uriparser.cpp b/libcmix-network/uriparser.cpp new file mode 100644 index 0000000..9cea452 --- /dev/null +++ b/libcmix-network/uriparser.cpp @@ -0,0 +1,3 @@ +#include "uriparser.hpp" + + diff --git a/libcmix-network/uriparser.hpp b/libcmix-network/uriparser.hpp new file mode 100644 index 0000000..c46b70a --- /dev/null +++ b/libcmix-network/uriparser.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include + +struct Uri { + std::string scheme; + std::string username; + std::string password; + std::string host; + std::string port; + std::string query; + std::string hash; +}; + +Uri parse_uri(std::string str) { + std::string scheme = "(?:(.+?)://)?"; + std::string uname_pass = "(?:(.*?)?(?::(.*?))@)?"; + std::string host = "(.+?)"; + std::string port = "(?::(\\d+?))?"; + std::string query = "(?:\\?(.+?))?"; + std::string hash = "(?:#(.+?))?"; + + std::regex expr("^" + scheme + uname_pass + host + port + query + hash + "$"); + std::smatch matches; + std::regex_match(str, matches, expr); + + return { + matches[1].str(), + matches[2].str(), + matches[3].str(), + matches[4].str(), + matches[5].str(), + matches[6].str(), + matches[7].str() + }; +} + +std::string debug_uri(Uri uri) { + std::stringstream ss; + ss << "scheme: " << uri.scheme << std::endl + << "username: " << uri.username << std::endl + << "password: " << uri.password << std::endl + << "host: " << uri.host << std::endl + << "port: " << uri.port << std::endl + << "query: " << uri.query << std::endl + << "hash: " << uri.hash << std::endl; + return ss.str(); +} + +std::string uri_to_string(Uri uri) { + return + (!uri.scheme.empty() ? uri.scheme + "://" : "") + + (!uri.username.empty() ? uri.username + (!uri.password.empty() ? ":" + uri.password : "") + "@" : "") + + uri.host + + (!uri.port.empty() ? ":" + uri.port : "") + + (!uri.query.empty() ? "?" + uri.query : ""); +} -- cgit v1.2.3-70-g09d2