From af04fc3ccbe1243dbb5472b2b2a9a1ff686c29c7 Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nwpope@utu.fi> Date: Wed, 3 Apr 2019 08:25:17 +0300 Subject: [PATCH] cppcheck on net module and update main.cpp to work --- net/cpp/CMakeLists.txt | 6 ++++ net/cpp/include/ftl/net/p2p.hpp | 14 ++++++-- net/cpp/include/ftl/net/socket.hpp | 7 ++++ net/cpp/include/ftl/uuid.hpp | 19 +++++++---- net/cpp/src/main.cpp | 18 ++++++---- net/cpp/src/socket.cpp | 53 ++++++++++++++++++++++++++---- net/cpp/test/CMakeLists.txt | 3 ++ 7 files changed, 98 insertions(+), 22 deletions(-) diff --git a/net/cpp/CMakeLists.txt b/net/cpp/CMakeLists.txt index 2eadfb088..1f80ac614 100644 --- a/net/cpp/CMakeLists.txt +++ b/net/cpp/CMakeLists.txt @@ -9,6 +9,8 @@ set(NETSOURCE src/socket.cpp src/dispatcher.cpp src/protocol.cpp + src/ws_internal.cpp + src/p2p.cpp ) #check_include_file("uriparser/Uri.h" HAVE_URI_H) @@ -20,4 +22,8 @@ check_function_exists(uriParseSingleUriA HAVE_URIPARSESINGLE) add_library(net ${NETSOURCE}) target_link_libraries(net pthread) +add_executable(net-cli src/main.cpp) +target_link_libraries(net-cli "${PROJECT_BINARY_DIR}/net/cpp/libnet.a" ${GLOG_LIBRARIES} ${URIPARSER_LIBRARIES} pthread readline uuid) +add_dependencies(net-cli net) + ADD_SUBDIRECTORY(test) diff --git a/net/cpp/include/ftl/net/p2p.hpp b/net/cpp/include/ftl/net/p2p.hpp index 76f2ca0ca..f9547dbde 100644 --- a/net/cpp/include/ftl/net/p2p.hpp +++ b/net/cpp/include/ftl/net/p2p.hpp @@ -23,12 +23,20 @@ namespace net { */ class P2P : public ftl::net::Protocol { public: - P2P(const char *uri); - P2P(const std::string &uri); + explicit P2P(const char *uri); + explicit P2P(const std::string &uri); void addPeer(std::shared_ptr<ftl::net::Socket> s) { peers_.push_back(s); }; + void addPeer(const std::string &uri) { + auto s = ftl::net::connect(uri.c_str()); + if (s->isValid()) peers_.push_back(s); + } + + const std::vector<std::shared_ptr<ftl::net::Socket>> &getPeers() const { + return peers_; + } - const UUID &id() const { return id_; } + const ftl::UUID &id() const { return id_; } /** * Bind a member function as an rpc "find one" across peers function. diff --git a/net/cpp/include/ftl/net/socket.hpp b/net/cpp/include/ftl/net/socket.hpp index a1c062a37..704ef00cc 100644 --- a/net/cpp/include/ftl/net/socket.hpp +++ b/net/cpp/include/ftl/net/socket.hpp @@ -5,6 +5,7 @@ #include <glog/logging.h> #include <ftl/net.hpp> #include <ftl/net/protocol.hpp> +#include <ftl/uri.hpp> #ifndef WIN32 #define INVALID_SOCKET -1 @@ -78,6 +79,8 @@ class Socket { * the same as the initial connection string on the client. */ std::string getURI() const { return uri_; }; + + std::string to_string() const { return peerid_; }; /** * Non-blocking Remote Procedure Call using a callback function. @@ -166,6 +169,7 @@ class Socket { bool valid_; bool connected_; int sock_; + ftl::URI::scheme_t scheme_; // Receive buffers size_t pos_; @@ -198,6 +202,9 @@ class Socket { template <typename... ARGS> int Socket::send(uint32_t s, ARGS... args) { + // Leave a blank entry for websocket header + if (scheme_ == ftl::URI::SCHEME_WS) send_vec_.push_back({nullptr,0}); + header_w_->service = s; header_w_->size = 4; send_vec_.push_back({header_w_,sizeof(ftl::net::Header)}); diff --git a/net/cpp/include/ftl/uuid.hpp b/net/cpp/include/ftl/uuid.hpp index e8bca1702..4a042c9cd 100644 --- a/net/cpp/include/ftl/uuid.hpp +++ b/net/cpp/include/ftl/uuid.hpp @@ -24,17 +24,24 @@ namespace ftl { #else uuid_generate(uuid_); #endif - }; - UUID(int u) { memset(&uuid_,u,16); }; - UUID(const UUID &u) { memcpy(&uuid_,&u.uuid_,16); } + } + explicit UUID(int u) { memset(&uuid_,u,16); } + UUID(const ftl::UUID &u) { memcpy(&uuid_,&u.uuid_,16); } - bool operator==(const UUID &u) const { return memcmp(&uuid_,&u.uuid_,16) == 0; } - bool operator!=(const UUID &u) const { return memcmp(&uuid_,&u.uuid_,16) != 0; } + UUID &operator=(const UUID &u) { + memcpy(&uuid_,&u.uuid_,16); return *this; + } + bool operator==(const UUID &u) const { + return memcmp(&uuid_,&u.uuid_,16) == 0; + } + bool operator!=(const UUID &u) const { + return memcmp(&uuid_,&u.uuid_,16) != 0; + } /** * Get a raw data string. */ - std::string str() const { return std::string((char*)&uuid_,16); }; + std::string str() const { return std::string((char*)&uuid_,16); } const unsigned char *raw() const { return (const unsigned char*)&uuid_; } /** diff --git a/net/cpp/src/main.cpp b/net/cpp/src/main.cpp index a63f538a6..34c1a1d73 100644 --- a/net/cpp/src/main.cpp +++ b/net/cpp/src/main.cpp @@ -13,7 +13,7 @@ using ftl::net::P2P; using ftl::net::Listener; using ftl::net::Socket; -static P2P p2p("ftl://cli"); +static P2P *p2p; static shared_ptr<Listener> listener = nullptr; static volatile bool stop = false; @@ -25,12 +25,12 @@ void handle_options(const char ***argv, int *argc) { if (cmd.find("--peer=") == 0) { cmd = cmd.substr(cmd.find("=")+1); //std::cout << "Peer added " << cmd.substr(cmd.find("=")+1) << std::endl; - p2p.addPeer(cmd); + p2p->addPeer(cmd); } else if (cmd.find("--listen=") == 0) { cmd = cmd.substr(cmd.find("=")+1); listener = ftl::net::listen(cmd.c_str()); - if (listener) listener->setProtocol(&p2p); - listener->onConnection([](shared_ptr<Socket> &s) { p2p.addPeer(s); }); + if (listener) listener->setProtocol(p2p); + listener->onConnection([](shared_ptr<Socket> &s) { p2p->addPeer(s); }); } (*argc)--; @@ -49,12 +49,12 @@ void handle_command(const char *l) { stop = true; } else if (cmd.find("peer ") == 0) { cmd = cmd.substr(cmd.find(" ")+1); - p2p.addPeer(cmd); + p2p->addPeer(cmd); } else if (cmd.find("list ") == 0) { cmd = cmd.substr(cmd.find(" ")+1); if (cmd == "peers") { - auto res = p2p.getPeers(); - for (auto r : res) std::cout << " " << r.to_string() << std::endl; + auto res = p2p->getPeers(); + for (auto r : res) std::cout << " " << r->to_string() << std::endl; } } } @@ -63,6 +63,8 @@ int main(int argc, const char **argv) { argc--; argv++; + p2p = new P2P("ftl://cli"); + // Process Arguments handle_options(&argv, &argc); @@ -79,6 +81,8 @@ int main(int argc, const char **argv) { stop = true; nthread.join(); + + delete p2p; return 0; } diff --git a/net/cpp/src/socket.cpp b/net/cpp/src/socket.cpp index a992cf055..1f2f13641 100644 --- a/net/cpp/src/socket.cpp +++ b/net/cpp/src/socket.cpp @@ -1,8 +1,11 @@ #define GLOG_NO_ABBREVIATED_SEVERITIES #include <glog/logging.h> +#include <fcntl.h> + #include <ftl/uri.hpp> #include <ftl/net/socket.hpp> +#include <ftl/net/ws_internal.hpp> #ifndef WIN32 #include <unistd.h> @@ -28,6 +31,8 @@ using namespace ftl; using ftl::net::Socket; using ftl::net::Protocol; +using ftl::URI; +using ftl::net::ws_connect; using namespace std; /*static std::string hexStr(const std::string &s) @@ -119,10 +124,6 @@ static int tcpConnect(URI &uri) { return csocket; } -static int wsConnect(URI &uri) { - return 1; -} - Socket::Socket(int s) : sock_(s), pos_(0), proto_(nullptr) { valid_ = true; @@ -151,12 +152,38 @@ Socket::Socket(const char *pUri) : pos_(0), uri_(pUri), proto_(nullptr) { connected_ = false; sock_ = INVALID_SOCKET; + scheme_ = uri.getProtocol(); if (uri.getProtocol() == URI::SCHEME_TCP) { sock_ = tcpConnect(uri); + +#ifdef WIN32 + u_long on = 1; + ioctlsocket(sock_, FIONBIO, &on); +#else + fcntl(sock_, F_SETFL, O_NONBLOCK); +#endif + valid_ = true; } else if (uri.getProtocol() == URI::SCHEME_WS) { - wsConnect(uri); - LOG(ERROR) << "Websocket currently unsupported"; + LOG(INFO) << "Websocket connect " << uri.getPath(); + sock_ = tcpConnect(uri); + if (sock_ != INVALID_SOCKET) { + if (!ws_connect(sock_, uri)) { + LOG(ERROR) << "Websocket connection failed"; + close(); + } + } else { + LOG(ERROR) << "Connection refused to " << uri.getHost() << ":" << uri.getPort(); + } + +#ifdef WIN32 + u_long on = 1; + ioctlsocket(sock_, FIONBIO, &on); +#else + fcntl(sock_, F_SETFL, O_NONBLOCK); +#endif + + valid_ = true; } else { LOG(ERROR) << "Unrecognised connection protocol: " << pUri; } @@ -395,6 +422,20 @@ void Socket::_connected() { } int Socket::_send() { + // Are we using a websocket? + if (scheme_ == ftl::URI::SCHEME_WS) { + // Create a websocket header as well. + size_t len = 0; + char buf[20]; // TODO(nick) Should not be a stack buffer. + for (auto v : send_vec_) { + len += v.iov_len; + } + int rc = ws_prepare(wsheader_type::BINARY_FRAME, false, len, buf, 20); + if (rc == -1) return -1; + send_vec_[0].iov_base = buf; + send_vec_[0].iov_len = rc; + } + #ifdef WIN32 // TODO(nick) Use WSASend instead int c = 0; diff --git a/net/cpp/test/CMakeLists.txt b/net/cpp/test/CMakeLists.txt index 03a789594..89a38738a 100644 --- a/net/cpp/test/CMakeLists.txt +++ b/net/cpp/test/CMakeLists.txt @@ -7,6 +7,7 @@ target_link_libraries(protocol_unit ${GLOG_LIBRARIES}) add_executable(socket_unit ./tests.cpp + ../src/ws_internal.cpp ./socket_unit.cpp ) target_include_directories(socket_unit PUBLIC ${PROJECT_SOURCE_DIR}/include) @@ -28,6 +29,7 @@ add_executable(p2p_base_unit ../src/protocol.cpp ../src/net.cpp ../src/listener.cpp + ../src/ws_internal.cpp ) target_include_directories(p2p_base_unit PUBLIC ${PROJECT_SOURCE_DIR}/include) target_link_libraries(p2p_base_unit ${URIPARSER_LIBRARIES} gflags ${GLOG_LIBRARIES} uuid) @@ -40,6 +42,7 @@ add_executable(net_integration ../src/listener.cpp ../src/protocol.cpp ../src/net.cpp + ../src/ws_internal.cpp ) target_include_directories(net_integration PUBLIC ${PROJECT_SOURCE_DIR}/include) target_link_libraries(net_integration ${URIPARSER_LIBRARIES} ${GLOG_LIBRARIES}) -- GitLab