diff --git a/CMakeLists.txt b/CMakeLists.txt index e792c5f..081bcb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,21 +4,35 @@ project(tablo) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Tablo shared libraries +# Build options -# libtabcrypt -add_subdirectory(lib/libtabcrypt) +option(DEF_LIBTABCRYPT "Build libtabcrypt" ON) +option(DEF_LIBTABNET "Build libtabnet" ON) -# libtabnet -add_subdirectory(lib/libtabnet) +option(DEF_CLIENT "Build TabloClient" ON) +option(DEF_MASTER "Build TabloMaster" ON) +option(DEF_NODE "Build TabloNode" ON) -# Test executables +# Shared libraries -add_subdirectory(TCTest) +if(DEF_LIBTABCRYPT) + add_subdirectory(lib/libtabcrypt) +endif() +if(DEF_LIBTABNET) + add_subdirectory(lib/libtabnet) +endif() -# TabloClient, TabloMaster and TabloNode executables (provided by own CMakeLists.txt files) +# Executables -add_subdirectory(TabloClient) -add_subdirectory(TabloMaster) -add_subdirectory(TabloNode) +if(DEF_CLIENT) + add_subdirectory(TabloClient) +endif() + +if(DEF_MASTER) + add_subdirectory(TabloMaster) +endif() + +if(DEF_NODE) + add_subdirectory(TabloNode) +endif() diff --git a/README.md b/README.md index 3471a24..fc618c1 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,11 @@ The following ports are used to establish the network tablo needs: ### 2 Deploy ```cmd -nix shell -./build-image-nix.sh -tablo-master --interface YOURINTERFACE -tablo-node --interface YOURINTERFACE -tablo-client --master YOURMASTERSIP +sudo nix-collect-garbage -d +nix build --log-format bar-with-logs +nix run .#tablo-master -- --interface INTERFACENAME +nix run .#tablo-node -- --interface INTERFACENAME +nix run .#tablo-client -- --master MASTERIPV4 ``` ## Deploy with DOCKER @@ -45,3 +45,7 @@ The flake in this repository allowes you to build minimal docker images that avo To use this feature, you NEED to use nix. Download available at: https://nixos.org/ +# Take a look at Tablos networking libs: +Tablo Transfer Protocol:TTP2 + +Tablo UDP Discovery: TUD diff --git a/TCTest/CMakeLists.txt b/TCTest/CMakeLists.txt deleted file mode 100644 index 9eee444..0000000 --- a/TCTest/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(tablo) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h") - -add_executable(tabcrypt-test ${SOURCES}) - -# Link against the tabcrypt library -target_link_libraries(tabcrypt-test PRIVATE tabcrypt) - -install(TARGETS tabcrypt-test DESTINATION bin) diff --git a/TCTest/src/main.cpp b/TCTest/src/main.cpp deleted file mode 100644 index 3d7b702..0000000 --- a/TCTest/src/main.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include "tabcrypt_test.h" - - -void handleLine(const std::string& line) { - if (encrypt_mode) { - std::cout << tabcrypt::encrypt(line, secret) << "\n"; - } else { - try { - std::cout << tabcrypt::decrypt(line, secret) << "\n"; - } catch (const std::exception& e) { - std::cerr << "Decryption failed: " << e.what() << "\n"; - } - } -} - - -/* - * Arguments: - * tabcrypt_test [-d|-e] - * Messages via stdin/stdout - */ -int main(int argc, char *argv[]) { - if (argc < 2) { - std::cerr << "Usage: " << argv[0] << " [-d|-e]\n" - " -d: decrypt (default)\n" - " -e: encrypt\n"; - return EXIT_FAILURE; - }; - std::string secret = argv[1]; - - // parse argv[2] - - if (std::string(argv[2]) == "-e") { - encrypt_mode = true; - } else if (std::string(argv[2]) != "-d") { - std::cerr << "Unknown option: " << argv[2] << "\n"; - return EXIT_FAILURE; - } - - std::string line; - - while (std::getline(std::cin, line)) { - if (line.empty()) { - break; // Exit on empty line - } - handleLine(line); - } -} diff --git a/TCTest/src/tabcrypt_test.h b/TCTest/src/tabcrypt_test.h deleted file mode 100644 index 4762f02..0000000 --- a/TCTest/src/tabcrypt_test.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Created by Tureb on 22.07.2025. -// - -#ifndef TABCRYPT_TEST_H -#define TABCRYPT_TEST_H - -inline bool encrypt_mode = false; -inline std::string secret; - -void handleLine(const std::string& line); - -#endif //TABCRYPT_TEST_H diff --git a/TabloClient/CMakeLists.txt b/TabloClient/CMakeLists.txt index b1ce592..2d2bfc0 100644 --- a/TabloClient/CMakeLists.txt +++ b/TabloClient/CMakeLists.txt @@ -8,8 +8,9 @@ file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h") add_executable(tablo-client ${SOURCES}) -# Link against the tabcrypt library +# Link against libs target_link_libraries(tablo-client PRIVATE tabcrypt) target_link_libraries(tablo-client PRIVATE tabnet) +target_link_libraries(tablo-client PRIVATE ttp2) install(TARGETS tablo-client DESTINATION bin) diff --git a/TabloClient/src/tabloClient.cpp b/TabloClient/src/tabloClient.cpp index 32c1080..d76a410 100644 --- a/TabloClient/src/tabloClient.cpp +++ b/TabloClient/src/tabloClient.cpp @@ -3,18 +3,27 @@ #include #include "utils/cli.h" +#include "utils/argv_struct.h" int main(int argc, char *argv[]) { if (argc > 0) { + struct Argv commandLineArguments; + for(int index = 0; index < argc; index++) { if (std::string(argv[index]).rfind("--master", 0) == 0) { - Cli cli(argv[index+1]); + commandLineArguments.tabloMaster = argv[index+1]; + } else if (std::string(argv[index]).rfind("--file", 0) == 0) { + commandLineArguments.filePath = argv[index+1]; } } + + if (commandLineArguments.tabloMaster.length() != 0) { + Cli cli(commandLineArguments); + } } else { // Use config file (TODO) - Cli cli(""); + std::wcout << "failed" << std::endl; } return 0; diff --git a/TabloClient/src/utils/argv_struct.h b/TabloClient/src/utils/argv_struct.h new file mode 100644 index 0000000..e73304c --- /dev/null +++ b/TabloClient/src/utils/argv_struct.h @@ -0,0 +1,11 @@ +#ifndef ARGV_STRUCT_H +#define ARGV_STRUCT_H + +#include + +struct Argv { + std::string tabloMaster; + std::string filePath; +}; + +#endif diff --git a/TabloClient/src/utils/cli.cpp b/TabloClient/src/utils/cli.cpp index 19238b4..ad8fae3 100644 --- a/TabloClient/src/utils/cli.cpp +++ b/TabloClient/src/utils/cli.cpp @@ -1,40 +1,134 @@ #include "cli.h" -#include +#include #include #include -#include +#include #include +#include -#include "networking.h" +#include "network_manager.h" -Cli::Cli(std::string tabloMaster) { +Cli::Cli(struct Argv argv) { + std::string tabloMaster = argv.tabloMaster; + std::string filePath = argv.filePath; + std::wcout << "Client! Tablo master at: " << tabloMaster.c_str() << std::endl; - Networking networking; + + NetworkManager networkManager; + + if (networkManager.createSocket(tabloMaster) < 0) { + std::wcout << "Create network manager failed!" << std::endl; + return; + } - std::thread networkingThread( - &Networking::networkingCycle, - &networking, - tabloMaster - ); + sendFile(filePath, &networkManager); while (true) { - int method; - std::wcout << "Method: "; - std::cin >> method; - std::wcout << std::endl; + std::wcout << "Choose option\n(1) send Packet\n(2) read Packets\n(3) send File\n(4) get Viewport\noption:"; + std::string option = ""; + std::cin >> option; + if (option == "1") { + std::string content; + std::wcout << "Content: "; + std::cin >> content; - std::string content; - std::wcout << "Content: "; - std::cin >> content; - std::wcout << std::endl; + ttp2::Networking::Packet packet; - networking.pushOrder(method, content); + ttp2::Networking::Standard payload; + payload.payload = content; + packet.payload = payload; - std::wcout << "Waiting for solution..." << std::endl; - while (!networking.hasSolution()) {} // Wait for solution + networkManager.pushRequest(packet); + } else if (option == "2") { + if (networkManager.hasResponse()) { + while (networkManager.hasResponse()) { + ttp2::ClientSessionController::Packet response = networkManager.popResponse(); + + if (std::holds_alternative(response.payload)) { + ttp2::ClientSessionController::Standard responsePayload = std::get(response.payload); + std::wcout << "Response:\nID: " << response.id << "\nPayload: " << responsePayload.payload.c_str() << std::endl; + } else if (std::holds_alternative(response.payload)) { + ttp2::ClientSessionController::File responsePayload = std::get(response.payload); + std::wcout << "Response:\nID: " << response.id + << "\n----payload----\nFilePath: " << responsePayload.filePath.c_str() + << "\nStart: " << responsePayload.start + << "\nEnd: " << responsePayload.end + << "\nPayload: " << responsePayload.payload.c_str() + << "\n---------------" << std::endl; + } else if (std::holds_alternative(response.payload)) { + ttp2::ClientSessionController::Viewport responseViewport = std::get(response.payload); + if (responseViewport.payload.length() > 0) { + std::wcout << responseViewport.payload.c_str() << std::endl; + } else { + std::wcout << "Empty Viewport" << std::endl; + } + } + } + } else { + std::wcout << "There are currently no packets to read!" << std::endl; + } + } else if (option == "3") { + std::string filePath; + std::wcout << "CSV Filepath:"; + std::cin >> filePath; + + sendFile(filePath, &networkManager); + } else if (option == "4") { + int xStart; + int xEnd; + int yStart; + int yEnd; - std::wcout << networking.popSolution().c_str() << std::endl; + std::wcout << "xStart:"; + std::cin >> xStart; + std::wcout << "xEnd:"; + std::cin >> xEnd; + std::wcout << "yStart:"; + std::cin >> yStart; + std::wcout << "yEnd:"; + std::cin >> yEnd; + + ttp2::Networking::Packet packet; + ttp2::Networking::Viewport payload; + payload.xStart = xStart; + payload.xEnd = xEnd; + payload.yStart = yStart; + payload.yEnd = yEnd; + packet.payload = payload; + + networkManager.pushRequest(packet); + std::wcout << "Send Viewport request!" << std::endl; + } else { + std::wcout << "invalid" << std::endl; + } } } +void Cli::sendFile(std::string filePath, NetworkManager* networkManager) { + if (filePath.length() != 0) { + std::ifstream file(filePath); + + if (file.is_open()) { + std::string fileContent; + std::string line; + int lineCount = 0; + while (std::getline(file, line)) { + lineCount++; + fileContent = fileContent + line.c_str() + "\n"; + } + file.close(); + + ttp2::Networking::Packet packet; + ttp2::Networking::File payload; + payload.filePath = filePath; + payload.start = 0; + payload.end = lineCount; + payload.payload = fileContent; + packet.payload = payload; + + networkManager->pushRequest(packet); + std::wcout << "Send file with FilePath: " << filePath.c_str() << std::endl; + } + } +} diff --git a/TabloClient/src/utils/cli.h b/TabloClient/src/utils/cli.h index a1783a4..812198f 100644 --- a/TabloClient/src/utils/cli.h +++ b/TabloClient/src/utils/cli.h @@ -1,12 +1,17 @@ #ifndef CLI_H #define CLI_H -#include +#include "network_manager.h" + +#include "argv_struct.h" class Cli { public: - Cli(std::string tabloMaster); + Cli(struct Argv argv); + + private: + void sendFile(std::string filePath, NetworkManager* networkManager); }; #endif diff --git a/TabloClient/src/utils/network_manager.cpp b/TabloClient/src/utils/network_manager.cpp new file mode 100644 index 0000000..0b96e43 --- /dev/null +++ b/TabloClient/src/utils/network_manager.cpp @@ -0,0 +1,51 @@ +#include "network_manager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NetworkManager::NetworkManager() {} + +int NetworkManager::createSocket(std::string tabloMaster) { + int serverSocket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + + sockaddr_in serverAddress; + serverAddress.sin_family = AF_INET; + serverAddress.sin_port = htons(4003); + serverAddress.sin_addr.s_addr = inet_addr(tabloMaster.c_str()); + + int connectionResult = connect(serverSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)); + + // Wait for server to accept + if (connectionResult < 0 && errno != EINPROGRESS) { + std::wcout << "Connection failed!" << std::endl; + return -1; + } + + clientSessionController = std::make_shared(serverSocket); + + std::thread networkThread([this]() { + clientSessionController->networkingSession(); + }); + networkThread.detach(); + + return 0; +} + +bool NetworkManager::hasResponse() { + return clientSessionController->hasResponse(); +} + +ttp2::ClientSessionController::Packet NetworkManager::popResponse() { + return clientSessionController->popResponse(); +} + +void NetworkManager::pushRequest(ttp2::Networking::Packet packet) { + clientSessionController->pushRequest(packet); +} diff --git a/TabloClient/src/utils/network_manager.h b/TabloClient/src/utils/network_manager.h new file mode 100644 index 0000000..dfec037 --- /dev/null +++ b/TabloClient/src/utils/network_manager.h @@ -0,0 +1,25 @@ +#ifndef NETWORK_MANAGER_H +#define NETWORK_MANAGER_H + +#include +#include +#include +#include +#include + +class NetworkManager +{ + public: + NetworkManager(); + + int createSocket(std::string tabloMaster); + + bool hasResponse(); + ttp2::ClientSessionController::Packet popResponse(); + void pushRequest(ttp2::ClientSessionController::Packet packet); + + private: + std::shared_ptr clientSessionController; +}; + +#endif diff --git a/TabloClient/src/utils/networking.cpp b/TabloClient/src/utils/networking.cpp deleted file mode 100644 index d67d8d0..0000000 --- a/TabloClient/src/utils/networking.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "networking.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tabnet.h" -#include "methods.h" - -Networking::Networking() {} - -void Networking::networkingCycle(std::string tabloMaster) { - // creating socket - int clientSocket = socket(AF_INET, SOCK_STREAM, 0); - - // specifying address - sockaddr_in serverAddress; - serverAddress.sin_family = AF_INET; - serverAddress.sin_port = htons(4003); - serverAddress.sin_addr.s_addr = inet_addr(tabloMaster.c_str()); - - // sending connection request - connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); - - while(true) { - int orderCollectionSize = orderCollection.size(); - tabnet::sendMessage(clientSocket, Methods::size, std::to_string(orderCollectionSize)); - tabnet::Packet response = tabnet::receiveMessage(clientSocket); - if (response.method == Methods::success) { - for(int index = 0; index < orderCollectionSize; index++) { - std::map order = orderCollection[0]; - orderCollection.erase(orderCollection.begin()); - int method = order.begin()->first; - - // Send data - tabnet::sendMessage(clientSocket, method, order[method]); - tabnet::Packet response = tabnet::receiveMessage(clientSocket); - if (response.method == Methods::success) { - std::wcout << "Send succeded!" << std::endl; - } else { - std::wcout << "Expected: " << Methods::success << " (success) or " << Methods::failed << " (failed), but got " << response.method << std::endl; - std::wcout << "With following payload" << response.payload.c_str() << std::endl; - } - } - } else if (response.method == Methods::failed) { - std::wcout << "Something went wrong while sending the size! Master response: " << response.payload.c_str() << std::endl; - } else { - std::wcout << "Expected: " << Methods::success << " (success) or " << Methods::failed << " (failed), but got " << response.method << std::endl; - std::wcout << "With following payload" << response.payload.c_str() << std::endl; - } - - //receive - tabnet::Packet receivedPacket = tabnet::receiveMessage(clientSocket); - if (receivedPacket.method == Methods::size) { - int count = std::stoi(receivedPacket.payload); - if (count != 0) { - tabnet::sendMessage(clientSocket, Methods::success, ""); - for(int i = 0; i < count; i++) { - tabnet::Packet response = tabnet::receiveMessage(clientSocket); - if (response.method == Methods::response) { - solutionCollection.push_back(response.payload); - tabnet::sendMessage(clientSocket, Methods::success, ""); - } else { - std::wcout << "Expected: " << Methods::response << " (response) got: " << receivedPacket.method << std::endl; - tabnet::sendMessage(clientSocket, Methods::failed, "Expected method response"); - } - } - } - } else { - std::wcout << "Expected: " << Methods::size << " (size) got: " << receivedPacket.method << std::endl; - tabnet::sendMessage(clientSocket, Methods::failed, "Expected method size"); - } - } -} - -bool Networking::hasSolution() { - std::lock_guard lock(mtx); - return !solutionCollection.empty(); -} - -std::string Networking::popSolution() { - std::lock_guard lock(mtx); - std::string solution = solutionCollection[0]; - solutionCollection.erase(solutionCollection.begin()); - return solution; -} - -void Networking::pushOrder(int method, std::string content) { - std::lock_guard lock(mtx); - std::map order; - order[method] = content; - orderCollection.push_back(order); -} - -bool Networking::isNumeric(const std::string& string) { - static const std::regex number_regex( - R"(^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$)" - ); - return std::regex_match(string, number_regex); -} - diff --git a/TabloClient/src/utils/networking.h b/TabloClient/src/utils/networking.h deleted file mode 100644 index b2f3c3f..0000000 --- a/TabloClient/src/utils/networking.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef NETWORKING_H -#define NETWORKING_H - -#include -#include -#include -#include - -class Networking -{ - public: - Networking(); - void networkingCycle(std::string tabloMaster); - - bool hasSolution(); - std::string popSolution(); - void pushOrder(int method, std::string content); - - private: - std::vector> orderCollection; - std::vector solutionCollection; - std::mutex mtx; - - std::string recieveMessage(int socket); - bool isNumeric(const std::string& string); -}; - -#endif diff --git a/TabloMaster/CMakeLists.txt b/TabloMaster/CMakeLists.txt index a0c58e5..f2db8bc 100644 --- a/TabloMaster/CMakeLists.txt +++ b/TabloMaster/CMakeLists.txt @@ -8,8 +8,10 @@ file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h") add_executable(tablo-master ${SOURCES}) -# Link against the tabcrypt and tabnet library +# Link against libs target_link_libraries(tablo-master PRIVATE tabcrypt) target_link_libraries(tablo-master PRIVATE tabnet) +target_link_libraries(tablo-master PRIVATE ttp2) +target_link_libraries(tablo-master PRIVATE tud) install(TARGETS tablo-master DESTINATION bin) diff --git a/TabloMaster/src/tabloMaster.cpp b/TabloMaster/src/tabloMaster.cpp index 7c2aeb6..b5a1174 100644 --- a/TabloMaster/src/tabloMaster.cpp +++ b/TabloMaster/src/tabloMaster.cpp @@ -1,23 +1,21 @@ #include #include -#include "utils/networking.h" +#include "utils/network_manager.h" int main(int argc, char *argv[]) { - // Prevents crash when tcp send failes - signal(SIGPIPE, SIG_IGN); - std::wcout << "Tablo Master" << std::endl; + if (argc > 0) { for(int index = 0; index < argc; index++) { if (std::string(argv[index]).rfind("--interface", 0) == 0) { - Networking networking(argv[index+1]); + NetworkManager networkManager(argv[index+1]); } } } else { // Use config file to set Interface (TODO) - Networking networking("eth0"); + NetworkManager networkManager("eth0"); } return 0; diff --git a/TabloMaster/src/utils/client_session_controller.cpp b/TabloMaster/src/utils/client_session_controller.cpp deleted file mode 100644 index 0854330..0000000 --- a/TabloMaster/src/utils/client_session_controller.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "client_session_controller.h" - -#include "tabnet.h" -#include "methods.h" - -#include -#include -#include -#include -#include -#include -#include - -ClientSessionManager::ClientSessionManager() {} - -ClientSessionManager::ClientSessionManager(int socket) { - setSocket(socket); -} - -void ClientSessionManager::setSocket(int socket) { - this->socket = socket; -} - -void ClientSessionManager::sessionControllerCycle() { - int responseCode = 0; - - while (responseCode >= 0) { - // Recieve orders - tabnet::Packet orderCount = tabnet::receiveMessage(this->socket); - if (orderCount.method == Methods::size) { - responseCode = tabnet::sendMessage(this->socket, Methods::success, ""); - - for (int index = 0; index < std::stoi(orderCount.payload); index++) { - orderCollection.push_back(tabnet::receiveMessage(this->socket)); - responseCode = tabnet::sendMessage(this->socket, Methods::success, ""); - } - } else { - responseCode = tabnet::sendMessage(this->socket, Methods::failed, ""); - std::wcout << "Something went wrong during receiving size!" << std::endl; - std::wcout << "Got: " << orderCount.method << " instead of " << Methods::size << " (size)" << std::endl; - } - - // Send solutions - int solutionCollectionSize = solutionCollection.size(); - responseCode = tabnet::sendMessage(this->socket, Methods::size, std::to_string(solutionCollectionSize)); - if (solutionCollectionSize > 0) { - if (tabnet::receiveMessage(this->socket).method == Methods::success) { - for(int index = 0; index < solutionCollectionSize; index++) { - responseCode = tabnet::sendMessage(this->socket, solutionCollection[0].method, solutionCollection[0].payload); - if (tabnet::receiveMessage(this->socket).method == Methods::success) { - solutionCollection.erase(solutionCollection.begin()); - } else { - std::wcout << "Send of solution failed!" << std::endl; - } - } - } else { - std::wcout << "Send of size failed!" << std::endl; - } - } - } - connected = false; -} - -bool ClientSessionManager::hasOrder() { - std::lock_guard lock(mtx); - return !orderCollection.empty(); -} - -bool ClientSessionManager::isConnected() { - std::lock_guard lock(mtx); - return connected; -} - -tabnet::Packet ClientSessionManager::popOrder() { - std::lock_guard lock(mtx); - if (!orderCollection.empty()) { - tabnet::Packet firstOrder = orderCollection[0]; - orderCollection.erase(orderCollection.begin()); - return firstOrder; - } - tabnet::Packet emptyPacket; - return emptyPacket; -} - -void ClientSessionManager::pushSolution(tabnet::Packet solution) { - std::lock_guard lock(mtx); - solutionCollection.push_back(solution); -} - -int ClientSessionManager::getOrderCollectionSize() { - std::lock_guard lock(mtx); - return orderCollection.size(); -} diff --git a/TabloMaster/src/utils/client_session_controller.h b/TabloMaster/src/utils/client_session_controller.h deleted file mode 100644 index 411a010..0000000 --- a/TabloMaster/src/utils/client_session_controller.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef CLIENT_SESSION_CONTROLLER_H -#define CLIENT_SESSION_CONTROLLER_H - -#include -#include -#include -#include "tabnet.h" - -class ClientSessionManager -{ - public: - ClientSessionManager(); - ClientSessionManager(int socket); - void sessionControllerCycle(); - bool isConnected(); - bool hasOrder(); - tabnet::Packet popOrder(); - int getOrderCollectionSize(); - void pushSolution(tabnet::Packet); - void setSocket(int socket); - - private: - int socket; - std::vector orderCollection; - std::vector solutionCollection; - bool connected = true; - std::mutex mtx; -}; - -#endif diff --git a/TabloMaster/src/utils/network_manager.cpp b/TabloMaster/src/utils/network_manager.cpp new file mode 100644 index 0000000..3bd6997 --- /dev/null +++ b/TabloMaster/src/utils/network_manager.cpp @@ -0,0 +1,165 @@ +#include "network_manager.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NetworkManager::NetworkManager(std::string interface) { + std::wcout << "Start socket..." << std::endl; + auto serverDiscovery = std::make_shared(interface, 4000, 4001, "Tablo"); + std::thread serverDiscoveryThread([serverDiscovery]() { + serverDiscovery->discoveryCycle(); + }); + this->udpDiscovery = std::move(serverDiscovery); + + ttp2::ServerSessionController tempServerSessionController; + std::string containerIP = tempServerSessionController.getLocalIpAddress(interface); + + sockaddr_in serverAddress; + serverAddress.sin_family = AF_INET; + serverAddress.sin_port = htons(4003); + serverAddress.sin_addr.s_addr = inet_addr(containerIP.c_str()); + + int serverSocket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + if(bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) { + std::wcout << "Bind failed!" << std::endl; + return; + } + + // Create epoll + int epollFd = epoll_create1(0); + if (epollFd == -1) { + std::wcout << "Failed to create epoll!" << std::endl; + } + // Set epoll action for server + struct epoll_event serverEvents; + serverEvents.events = EPOLLIN; + serverEvents.data.fd = serverSocket; + if (epoll_ctl(epollFd, EPOLL_CTL_ADD, serverSocket, &serverEvents) == -1) { + std::wcout << "Failed to set epoll_ctl!" << std::endl; + return; + } + + listen(serverSocket, 5); + std::vector clientConnections; + while (true) { + const int MAX_EVENTS = 10; + struct epoll_event events[MAX_EVENTS]; + int epollRequestCount = epoll_wait(epollFd, events, MAX_EVENTS, -1); + + for (int index = 0; index < epollRequestCount; ++index) { + if (events[index].data.fd == serverSocket) { + int clientSocket = accept4(serverSocket, nullptr, nullptr, SOCK_NONBLOCK); + std::wcout << "New clientSocket: " << clientSocket << std::endl; + + clientConnections.push_back(std::thread([this, serverSocket, clientSocket]() { + this->handleClientConnection(serverSocket, clientSocket); + })); + } + } + } +} + +void NetworkManager::handleClientConnection(int serverSocket, int clientSocket) { + std::wcout << "Handle client conn" << std::endl; + std::vector nodeConnections; + + auto serverSessionController = std::make_shared(serverSocket, clientSocket); + + std::thread networkingSession([serverSessionController]() { + serverSessionController->networkingSession(); + }); + + while(serverSessionController->isConnected()) { + // Establish new node connections + std::vector discoveredNodes = udpDiscovery->getDiscoveredAddresses(); + + for (int newNodeIndex = 0; newNodeIndex < discoveredNodes.size(); newNodeIndex++) { + bool isNew = true; + for (int index = 0; index < nodeConnections.size(); index++) { + if (nodeConnections[index].ip == discoveredNodes[index]) { + isNew = false; + } + } + + if (isNew) { + std::wcout << "Create new conn!" << std::endl; + std::string nodeIpv4 = discoveredNodes[newNodeIndex]; + + int nodeSocket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + + sockaddr_in nodeAddress; + nodeAddress.sin_family = AF_INET; + nodeAddress.sin_port = htons(4004); + nodeAddress.sin_addr.s_addr = inet_addr(nodeIpv4.c_str()); + + int connectionResult = connect(nodeSocket, (struct sockaddr*) &nodeAddress, sizeof(nodeAddress)); + + // Wait for server to accept + if (connectionResult < 0 && errno != EINPROGRESS) { + std::wcout << "Connection failed!" << std::endl; + continue; + } + + std::shared_ptr clientSessionController = std::make_shared(nodeSocket); + + std::thread networkThread([clientSessionController]() { + clientSessionController->networkingSession(); + }); + networkThread.detach(); + + Nodes newNode = {nodeIpv4, clientSessionController}; + nodeConnections.push_back(newNode); + std::wcout << "Done!" << std::endl; + } + } + + // Remove disconnected nodes + for (int index = 0; index < nodeConnections.size(); index++) { + if(!nodeConnections[index].node->isConnected()) { + std::wcout << "node with ip: " << nodeConnections[index].ip.c_str() << " disconnected!" << std::endl; + nodeConnections.erase(nodeConnections.begin() + index); + } + } + + // Handle common business + // WARNING: This is only temporary. The distribution logic has to be rewritten later + + // Send request + if (serverSessionController->hasRequest()) { + ttp2::ServerSessionController::Packet packet = serverSessionController->popRequest(); + std::wcout << "Received packet id: " << packet.id << std::endl; + + for (int index = 0; index < nodeConnections.size(); index++) { + nodeConnections[index].node->pushRequest(packet); + } + } + + // Receive response + for (int index = 0; index < nodeConnections.size(); index++) { + while(nodeConnections[index].node->hasResponse()) { + serverSessionController->pushResponse(nodeConnections[index].node->popResponse()); + } + } + } + + // Disconnect node conns if client disconnects + for (int index = 0; index < nodeConnections.size(); index++) { + nodeConnections[index].node->disconnect(); + } + + std::wcout << "Terminated!" << std::endl; + networkingSession.detach(); + + serverDiscoveryThread.join(); +} diff --git a/TabloMaster/src/utils/network_manager.h b/TabloMaster/src/utils/network_manager.h new file mode 100644 index 0000000..9a2dfa2 --- /dev/null +++ b/TabloMaster/src/utils/network_manager.h @@ -0,0 +1,26 @@ +#ifndef NETWORK_MANAGER_H +#define NETWORK_MANAGER_H + +#include +#include +#include +#include +#include + +class NetworkManager +{ + public: + NetworkManager(std::string interface); + void handleClientConnection(int serverSocket, int clientSocket); + + private: + struct Nodes { + std::string ip; + std::shared_ptr node; + }; + + std::shared_ptr udpDiscovery; + std::thread serverDiscoveryThread; +}; + +#endif diff --git a/TabloMaster/src/utils/networking.cpp b/TabloMaster/src/utils/networking.cpp deleted file mode 100644 index 2a92575..0000000 --- a/TabloMaster/src/utils/networking.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "node_session_controller.h" -#include "udp_discovery.h" - -#include "tabnet.h" -#include "networking.h" -#include "methods.h" -#include "client_session_controller.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Networking::Networking(std::string interface) { - std::wcout << "Start socket..." << std::endl; - udpDiscoveryThread = std::thread(&UdpDiscovery::udpDiscoveryCycle, &udpDiscovery, interface); - - // Client socket - int serverSocket = socket(AF_INET, SOCK_STREAM, 0); - - sockaddr_in serverAddress; - serverAddress.sin_family = AF_INET; - serverAddress.sin_port = htons(4003); - serverAddress.sin_addr.s_addr = inet_addr(tabnet::getLocalIpAddress(interface).c_str()); - - bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)); - listen(serverSocket, 5); - - while (true) { - int clientSocket = accept(serverSocket, nullptr, nullptr); - std::wcout << "New client connection!" << std::endl; - clientConnections.push_back(std::thread( - &Networking::handleClientConnection, - this, - serverSocket, clientSocket - )); - } -} - -void Networking::handleClientConnection(int serverSocket, int clientSocket) { - ClientSessionManager clientSessionManager(clientSocket); - - std::thread clientThread( - &ClientSessionManager::sessionControllerCycle, - &clientSessionManager - ); - - // TCP - std::vector nodeIps; - int responseCode = 0; - while (clientSessionManager.isConnected()) { - std::vector newNodeIps = udpDiscovery.getNodeAdresses(); - nodeIps = getIps(); - - // sort vectors to compare them - std::sort(newNodeIps.begin(), newNodeIps.end()); - std::sort(nodeIps.begin(), nodeIps.end()); - - if(newNodeIps.size() == 0) { - std::wcout << "No connected nodes!" << std::endl; - if (nodeIps.size() > 0) { - // Close connections with nodes that dont exist anymore - for (int index = 0; index < nodeIps.size(); index++) { - std::wcout << "Close connection: " << nodeIps[index].c_str() << std::endl; - close(getConnectionAtIp(nodeIps[index])->socket); - removeConnectionAtIp(nodeIps[index]); - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } else if(newNodeIps == nodeIps) { - bool nodeShutdown = false; - while (!nodeShutdown) { - // TODO: Replace with real distribution later - std::vector orders; - while(clientSessionManager.hasOrder()) { - orders.push_back(clientSessionManager.popOrder()); - } - - for (int i = 0; i < connections.size(); i++) { - Connection* currentConnection = &connections[i]; - - for (int j = 0; j < orders.size(); j++) { - currentConnection->controller->pushOrder(orders[j]); - } - - while (currentConnection->controller->hasSolution()) { - clientSessionManager.pushSolution( - currentConnection->controller->popSolution() - ); - } - } - } - } else if (newNodeIps != nodeIps) { - std::wcout << "New nodes!" << std::endl; - - // Create connections with nodes - for (int index = 0; index < newNodeIps.size(); index++) { - // If newNodeIps[index] not in nodeIps (keys of connections) - if(std::find(nodeIps.begin(), nodeIps.end(), newNodeIps[index]) == nodeIps.end()) { - // Create new connection - int newSocket = socket(AF_INET, SOCK_STREAM, 0); - - sockaddr_in nodeAddress; - nodeAddress.sin_family = AF_INET; - nodeAddress.sin_port = htons(4004); - nodeAddress.sin_addr.s_addr = inet_addr(newNodeIps[index].c_str()); - - if(connect(newSocket, (struct sockaddr*) &nodeAddress, sizeof(nodeAddress)) == -1) { - udpDiscovery.removeNodeAddress(newNodeIps[index]); - continue; - } - - tabnet::Packet responseCode = tabnet::receiveMessage(newSocket); - - // handshake compleate - if(responseCode.method == Methods::success) { - auto nodeSessionController = std::make_unique(); - - std::thread nodeSessionCycleThread( - &NodeSessionController::sessionControllerCycle, - nodeSessionController.get(), - newSocket - ); - - connections.emplace_back(Connection{ - newNodeIps[index], - newSocket, - std::move(nodeSessionCycleThread), - std::move(nodeSessionController) - }); - - std::wcout << "Connection established: " << responseCode.method << " at ip: " << newNodeIps[index].c_str() << " | Connections.size(): " << connections.size() << std::endl; - } - } - } - std::wcout << "[CLOSE] Connections with nodes that dont exist anymore" << std::endl; - // Close connections with nodes that dont exist anymore - for (int index = 0; index < nodeIps.size(); index++) { - std::wcout << "Iterating over nodeIPS" << std::endl; - if(std::find(newNodeIps.begin(), newNodeIps.end(), nodeIps[index]) == newNodeIps.end()) { - // NOTE: This is NOT tested! (yet) - std::wcout << "Close connection: " << nodeIps[index].c_str() << std::endl; - close(getConnectionAtIp(nodeIps[index])->socket); - removeConnectionAtIp(nodeIps[index]); - nodeIps.erase(nodeIps.begin() + index); - } - } - } else { - std::wcout << "unknown operation!" << std::endl; - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - } - - // Close node con - for(int index = 0; index < connections.size(); index++) { - close(getConnectionAtIp(nodeIps[index])->socket); - } - std::wcout << "Terminate handleClientConnection for " << clientSocket << std::endl; - udpDiscoveryThread.join(); -} - -std::vector Networking::getIps() { - std::vector keys; - for (const Connection& con : connections) { - keys.push_back(con.ip); - } - return keys; -} - -void Networking::removeConnectionAtIp(std::string ip) { - for (int index = 0; index < connections.size(); index++) { - if (connections[index].ip == ip) { - connections.erase(connections.begin() + index); - return; - } - } -} - -Networking::Connection* Networking::getConnectionAtIp(std::string ip) { - for (int index = 0; index < connections.size(); index++) { - if (connections[index].ip == ip) { - return &connections[index]; - } - } - return nullptr; -} diff --git a/TabloMaster/src/utils/networking.h b/TabloMaster/src/utils/networking.h deleted file mode 100644 index 21ef557..0000000 --- a/TabloMaster/src/utils/networking.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef NETWORKING_H -#define NETWORKING_H - -#include -#include -#include -#include - -#include "udp_discovery.h" -#include "node_session_controller.h" - -class Networking -{ - public: - Networking(std::string interface); - void handleClientConnection(int serverSocket, int clientSocket); - - private: - struct Connection { - std::string ip; - int socket; - std::thread thread; - std::unique_ptr controller; - - Connection(std::string ip_, int sock_, std::thread t, std::unique_ptr ctrl): ip(std::move(ip_)), socket(sock_), thread(std::move(t)), controller(std::move(ctrl)) {} - }; - - std::vector connections; - std::vector clientConnections; - UdpDiscovery udpDiscovery; - std::thread udpDiscoveryThread; - - std::vector getIps(); - void removeConnectionAtIp(std::string ip); - Connection* getConnectionAtIp(std::string ip); -}; - -#endif diff --git a/TabloMaster/src/utils/node_session_controller.cpp b/TabloMaster/src/utils/node_session_controller.cpp deleted file mode 100644 index 2a4dc85..0000000 --- a/TabloMaster/src/utils/node_session_controller.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "node_session_controller.h" - -#include "tabnet.h" -#include "methods.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -NodeSessionController::NodeSessionController() {} - -void NodeSessionController::sessionControllerCycle(int socket) { - this->socket = socket; - std::wcout << "CYCLE STARTED" << std::endl; - - int responseCode = 0; - - while (responseCode >= 0) { - // Receive solutions - tabnet::Packet solutionCount = tabnet::receiveMessage(socket); - std::wcout << "solutionCount " << solutionCount.method << " payload " << solutionCount.payload.c_str() << std::endl; - if (solutionCount.method == Methods::size) { - responseCode = tabnet::sendMessage(socket, Methods::success, ""); - - for (int index = 0; index < std::stoi(solutionCount.payload); index++) { - tabnet::Packet packet = tabnet::receiveMessage(socket); - std::wcout << "GOT SOLUTION -----> " << packet.method << std::endl; - pushSolution(packet); - responseCode = tabnet::sendMessage(socket, Methods::success, ""); - } - } else { - responseCode = tabnet::sendMessage(socket, Methods::failed, ""); - std::wcout << "Something went wrong during receiving size!" << std::endl; - std::wcout << "Got: " << solutionCount.method << " instead of " << Methods::size << " (size)" << std::endl; - } - - tabnet::Packet ready = tabnet::receiveMessage(socket); - - // Send orders - int orderCollectionSize = getOrderCollectionSize(); - responseCode = tabnet::sendMessage(socket, Methods::size, std::to_string(orderCollectionSize)); - if (orderCollectionSize > 0) { - if (tabnet::receiveMessage(socket).method == Methods::success) { - for(int index = 0; index < orderCollectionSize; index++) { - responseCode = tabnet::sendPacket(socket, popOrder()); - tabnet::Packet response = tabnet::receiveMessage(socket); - if (response.method != Methods::success) { - std::wcout << "Send order to node failed: got " << response.method << std::endl; - } - } - } else { - std::wcout << "Send of size failed!" << std::endl; - } - } - - if (responseCode < 0) { - // TODO: FIX THIS - responseCode = 0; - //udpDiscovery.removeNodeAddress(nodeIps[index]); - connected = false; - break; - } - } - connected = false; -} - -bool NodeSessionController::hasSolution() { - std::lock_guard lock(mtx); - return !solutionCollection.empty(); -} - -bool NodeSessionController::hasOrder() { - std::lock_guard lock(mtx); - return !orderCollection.empty(); -} - -bool NodeSessionController::isConnected() { - std::lock_guard lock(mtx); - return connected; -} - -tabnet::Packet NodeSessionController::popOrder() { - return popCollection(orderCollection); -} - -tabnet::Packet NodeSessionController::popSolution() { - return popCollection(solutionCollection); -} - -tabnet::Packet NodeSessionController::popCollection(std::vector collection) { - std::lock_guard lock(mtx); - if (!collection.empty()) { - tabnet::Packet firstOrder = collection[0]; - collection.erase(collection.begin()); - return firstOrder; - } - tabnet::Packet emptyPacket; - return emptyPacket; -} - -void NodeSessionController::pushSolution(tabnet::Packet solution) { - std::lock_guard lock(mtx); - solutionCollection.push_back(solution); -} - -void NodeSessionController::pushOrder(tabnet::Packet order) { - std::lock_guard lock(mtx); - orderCollection.push_back(order); -} - -int NodeSessionController::getOrderCollectionSize() { - std::lock_guard lock(mtx); - return orderCollection.size(); -} diff --git a/TabloMaster/src/utils/node_session_controller.h b/TabloMaster/src/utils/node_session_controller.h deleted file mode 100644 index c2251cc..0000000 --- a/TabloMaster/src/utils/node_session_controller.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef NODE_SESSION_CONTROLLER_H -#define NODE_SESSION_CONTROLLER_H - -#include -#include -#include -#include "tabnet.h" - -class NodeSessionController -{ - public: - NodeSessionController(); - void sessionControllerCycle(int socket); - bool isConnected(); - bool hasOrder(); - bool hasSolution(); - tabnet::Packet popOrder(); - tabnet::Packet popSolution(); - int getOrderCollectionSize(); - void pushSolution(tabnet::Packet); - void pushOrder(tabnet::Packet order); - - private: - int socket; - std::vector orderCollection; - std::vector solutionCollection; - bool connected = true; - std::mutex mtx; - tabnet::Packet popCollection(std::vector collection); -}; - -#endif diff --git a/TabloMaster/src/utils/udp_discovery.cpp b/TabloMaster/src/utils/udp_discovery.cpp deleted file mode 100644 index 6c3600a..0000000 --- a/TabloMaster/src/utils/udp_discovery.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "udp_discovery.h" - -#include "tabnet.h" -#include "methods.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void UdpDiscovery::udpDiscoveryCycle(std::string interface) { - std::wcout << "Start Udp discovery..." << std::endl; - - std::string containerIP = tabnet::getLocalIpAddress(interface); - std::string broadcastIP = tabnet::getBroadcastIpAddress(); - - std::wcout << "Container IP: " << containerIP.c_str() << " | Broadcast IP: " << broadcastIP.c_str() << std::endl; - - if (containerIP.empty()) { - std::wcout << "Failed to find container IP!" << std::endl; - return; - } - - if (broadcastIP.empty()) { - std::wcout << "Failed to find broadcast IP!" << std::endl; - return; - } - - // Init: server socket - int serverSocket; - struct sockaddr_in broadcast{}, receiverAddress{}; - const int port = 4000; - - // Create socket - if ((serverSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - std::wcout << "Failed to create Socket!" << std::endl; - return; - } - // Enable broadcast - int broadcastBind = 1; - if (setsockopt(serverSocket, SOL_SOCKET, SO_BROADCAST, &broadcastBind, sizeof(broadcastBind)) < 0) { - std::wcout << "Failed to enable broadcast!" << std::endl; - close(serverSocket); - return; - } - // Allow reuse - int reuse = 1; - if (setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { - std::wcout << "Setsockopt failed!" << std::endl; - close(serverSocket); - return; - } - - // clear garbage - memset(&broadcast, 0, sizeof(broadcast)); - // prepare socket - broadcast.sin_family = AF_INET; - broadcast.sin_port = htons(port); - - if (inet_pton(AF_INET, broadcastIP.c_str(), &broadcast.sin_addr) <= 0) { - std::wcout << "Invalid broadcast IP" << std::endl; - close(serverSocket); - return; - } - - // Init recieve socket - int tcpMasterSocket, tcpNodeSocket; - struct sockaddr_in tcpAddress; - int opt = 1; - socklen_t addrlen = sizeof(tcpAddress); - if ((tcpMasterSocket = socket(AF_INET, SOCK_STREAM, 0)) == 0) { - std::wcout << "socket failed" << std::endl; - return; - } - if (setsockopt(tcpMasterSocket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { - std::wcout << "Setsockopt failed!" << std::endl; - return; - } - tcpAddress.sin_family = AF_INET; - tcpAddress.sin_addr.s_addr = inet_addr(containerIP.c_str()); - tcpAddress.sin_port = htons(4001); - if (bind(tcpMasterSocket, (struct sockaddr*)&tcpAddress, sizeof(tcpAddress)) < 0) { - std::wcout << "Bind failed!" << std::endl; - return; - } - if (listen(tcpMasterSocket, 3) < 0) { - std::wcout << "Listen failed!" << std::endl; - return; - } - - while(true) { - // Send message - if (tabnet::sendMessageTo(serverSocket, broadcast, Methods::ip, containerIP.c_str()) != 0) { - std::wcout << "Broadcast failed!" << std::endl; - return; - } - - // Accept incoming connection - int flags = fcntl(tcpMasterSocket, F_GETFL, 0); - fcntl(tcpMasterSocket, F_SETFL, flags | O_NONBLOCK); - - int tcpNodeSocket = -1; - time_t start = time(nullptr); - while (time(nullptr) - start < 5) { - tcpNodeSocket = accept(tcpMasterSocket, (struct sockaddr*)&tcpAddress, (socklen_t*)&addrlen); - if (tcpNodeSocket >= 0) break; - usleep(100000); - } - - if (tcpNodeSocket < 0) { - // DEBUG ONLY: - //std::wcout << "Timeout: no connection" << std::endl; - continue; - } else { - // tabnet::Packet data; - // ssize_t valread = read(tcpNodeSocket, (char*)&data, sizeof(data)-1); - - tabnet::Packet data = tabnet::receiveMessage(tcpNodeSocket); - - // Add ip to discovered Ip's if not already in vector - if (data.method == Methods::ip && std::find(nodeIPAddresses.begin(), nodeIPAddresses.end(), std::string(data.payload)) == nodeIPAddresses.end()) { - nodeIPAddresses.push_back(std::string(data.payload)); - } - - close(tcpNodeSocket); - } - usleep(100000); - } - close(serverSocket); - std::wcout << "UDP socket closed..." << std::endl; -} - -std::vector UdpDiscovery::getNodeAdresses() { - std::lock_guard lock(mtx); - return nodeIPAddresses; -} - -void UdpDiscovery::removeNodeAddress(std::string nodeAddress) { - std::lock_guard lock(mtx); - nodeIPAddresses.erase(find(nodeIPAddresses.begin(), nodeIPAddresses.end(), nodeAddress)); -} - diff --git a/TabloMaster/src/utils/udp_discovery.h b/TabloMaster/src/utils/udp_discovery.h deleted file mode 100644 index 449152c..0000000 --- a/TabloMaster/src/utils/udp_discovery.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef UDP_DISCOVERY_H -#define UDP_DISCOVERY_H - -#include -#include -#include - -class UdpDiscovery -{ - public: - void udpDiscoveryCycle(std::string interface); - std::vector getNodeAdresses(); - void removeNodeAddress(std::string nodeAddress); - - private: - std::vector nodeIPAddresses = {}; - std::mutex mtx; -}; - -#endif diff --git a/TabloNode/CMakeLists.txt b/TabloNode/CMakeLists.txt index ed598d5..5dddf39 100644 --- a/TabloNode/CMakeLists.txt +++ b/TabloNode/CMakeLists.txt @@ -8,8 +8,10 @@ file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h") add_executable(tablo-node ${SOURCES}) -# Link against the tabcrypt and tabnet library +# Link against libs target_link_libraries(tablo-node PRIVATE tabcrypt) target_link_libraries(tablo-node PRIVATE tabnet) +target_link_libraries(tablo-node PRIVATE ttp2) +target_link_libraries(tablo-node PRIVATE tud) install(TARGETS tablo-node DESTINATION bin) diff --git a/TabloNode/src/tabloNode.cpp b/TabloNode/src/tabloNode.cpp index 4052c80..b5d9c62 100644 --- a/TabloNode/src/tabloNode.cpp +++ b/TabloNode/src/tabloNode.cpp @@ -1,23 +1,20 @@ -#include +#include #include -#include "utils/networking.h" +#include "utils/network_manager.h" int main(int argc, char *argv[]) -{ - // Prevents crash when tcp send failes - signal(SIGPIPE, SIG_IGN); - +{ std::wcout << "Tablo Node" << std::endl; if (argc > 0) { for(int index = 0; index < argc; index++) { if (std::string(argv[index]).rfind("--interface", 0) == 0) { - Networking networking(argv[index+1]); + NetworkManager networkManager(argv[index+1]); } } } else { // Use config file to set Interface (TODO) - Networking networking("eth0"); + NetworkManager networking("eth0"); } return 0; diff --git a/TabloNode/src/utils/csv_manager.cpp b/TabloNode/src/utils/csv_manager.cpp new file mode 100644 index 0000000..9929fbf --- /dev/null +++ b/TabloNode/src/utils/csv_manager.cpp @@ -0,0 +1,116 @@ +#include "csv_manager.h" + +#include + +#include +#include +#include +#include + +void CsvManager::setFile(ttp2::ServerSessionController::File newFile) { + this->file = newFile; +} + +std::string CsvManager::getFilePath() { + return this->file.filePath; +} + +int CsvManager::getRowCount() { + int count = 0; + for (int index = 0; index < this->file.payload.length(); index++) + if (this->file.payload[index] == '\n') + count++; + return count; +} + +int CsvManager::getColumnCount() { + // get position of first linebreak + std::string delimiter = "\n"; + const std::boyer_moore_searcher searcher(delimiter.begin(), delimiter.end()); + const auto distanceToDelimiter = std::search(this->file.payload.begin(), this->file.payload.end(), searcher); + if (distanceToDelimiter != this->file.payload.end()) { + // substring first row + std::string firstRow = this->file.payload.substr(0, std::distance(this->file.payload.begin(), distanceToDelimiter)); + + int count = 1; + for (int index = 0; index < firstRow.length(); index++) + if (firstRow[index] == ',') + count++; + return count; + } else + return 0; +} + +std::string CsvManager::getRowByIndex(int index) { + std::string resultRow = ""; + + if (index < 1) { + return resultRow; + } else if (index <= getRowCount()) { + int count = 0; + if (index == 1) { + for (int countIndex = 0; countIndex < this->file.payload.length(); countIndex++) { + if (this->file.payload[countIndex] == '\n') + return resultRow; + resultRow = resultRow + this->file.payload[countIndex]; + } + } + + for (int countIndex = 0; countIndex < this->file.payload.length(); countIndex++) { + if (this->file.payload[countIndex] == '\n') { + if (count < index) + count++; + if (count == index) + break; + } else if (count == index-1) { + resultRow = resultRow + this->file.payload[countIndex]; + } + } + return resultRow; + } else { + return resultRow; + } +} + +std::string CsvManager::getColumnByIndex(int index) { + return getColumnByIndex(index, this->file.payload); +} + +std::string CsvManager::getColumnByIndex(int index, std::string rows) { + std::string resultRow; + + int column = 0; + for (int countIndex = 0; countIndex < rows.length(); countIndex++) { + if (rows[countIndex] == '\n') { + resultRow = resultRow + '\n'; + column = 0; + continue; + } else if (rows[countIndex] == ',') { + column++; + continue; + } + if (column == index-1) { + resultRow = resultRow + rows[countIndex]; + } + } + + return resultRow; +} + +std::string CsvManager::getViewport(int xStart, int xEnd, int yStart, int yEnd) { + std::string resultPayload = ""; + for (int xIndex = xStart; xIndex <= xEnd; xIndex++) { + std::string currentRow = getRowByIndex(xIndex); + + std::string resultRow = ""; + for (int yIndex = yStart; yIndex <= yEnd; yIndex++) { + resultRow = resultRow + getColumnByIndex(yIndex, currentRow); + if (yIndex != yEnd) { + resultRow = resultRow + ','; + } + } + + resultPayload = resultPayload + resultRow + '\n'; + } + return resultPayload; +} diff --git a/TabloNode/src/utils/csv_manager.h b/TabloNode/src/utils/csv_manager.h new file mode 100644 index 0000000..6661c2f --- /dev/null +++ b/TabloNode/src/utils/csv_manager.h @@ -0,0 +1,23 @@ +#ifndef CSV_MANAGER_H +#define CSV_MANAGER_H + +#include + +#include + +class CsvManager { + public: + void setFile(ttp2::ServerSessionController::File newFile); + std::string getFilePath(); + int getRowCount(); + int getColumnCount(); + std::string getRowByIndex(int index); + std::string getColumnByIndex(int index); + std::string getColumnByIndex(int index, std::string rows); + std::string getViewport(int xStart, int xEnd, int yStart, int yEnd); + + private: + ttp2::ServerSessionController::File file; +}; + +#endif diff --git a/TabloNode/src/utils/network_manager.cpp b/TabloNode/src/utils/network_manager.cpp new file mode 100644 index 0000000..a02d646 --- /dev/null +++ b/TabloNode/src/utils/network_manager.cpp @@ -0,0 +1,109 @@ +#include "network_manager.h" + +#include +#include + +#include "worker.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NetworkManager::NetworkManager(std::string interface) { + std::wcout << "Start Socket...." << std::endl; + ttp2::ServerSessionController serverSessionController; + + std::string containerIP = serverSessionController.getLocalIpAddress(interface); + + auto clientDiscovery = std::make_shared(interface, 4000, 4001, "Tablo"); + std::thread udpThread([clientDiscovery]() { + clientDiscovery->discoveryCycle(); + }); + + sockaddr_in serverAddress; + serverAddress.sin_family = AF_INET; + serverAddress.sin_port = htons(4004); + serverAddress.sin_addr.s_addr = inet_addr(containerIP.c_str()); + + int serverSocket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + if(bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) { + std::wcout << "Bind failed!" << std::endl; + return; + } + + // Create epoll + int epollFd = epoll_create1(0); + if (epollFd == -1) { + std::wcout << "Failed to create epoll!" << std::endl; + } + // Set epoll action for server + struct epoll_event serverEvents; + serverEvents.events = EPOLLIN; + serverEvents.data.fd = serverSocket; + if (epoll_ctl(epollFd, EPOLL_CTL_ADD, serverSocket, &serverEvents) == -1) { + std::wcout << "Failed to set epoll_ctl!" << std::endl; + return; + } + + listen(serverSocket, 5); + std::vector clientConnections; + while (true) { + const int MAX_EVENTS = 10; + struct epoll_event events[MAX_EVENTS]; + int epollRequestCount = epoll_wait(epollFd, events, MAX_EVENTS, -1); + + for (int index = 0; index < epollRequestCount; ++index) { + if (events[index].data.fd == serverSocket) { + int clientSocket = accept4(serverSocket, nullptr, nullptr, SOCK_NONBLOCK); + std::wcout << "New clientSocket: " << clientSocket << std::endl; + + clientConnections.push_back(std::thread([this, serverSocket, clientSocket]() { + this->handleClientConnection(serverSocket, clientSocket); + })); + } + } + } + + std::wcout << "Terminated!" << std::endl; + + for (auto &socketThread : clientConnections) { + if (socketThread.joinable()) { + socketThread.join(); + } + } + + if (udpThread.joinable()) { + udpThread.join(); + } +} + +void NetworkManager::handleClientConnection(int serverSocket, int clientSocket) { + auto serverSessionController = std::make_shared(serverSocket, clientSocket); + + std::thread networkingSession([serverSessionController]() { + serverSessionController->networkingSession(); + }); + + Worker worker; + std::thread workerThread = std::thread(&Worker::solveRequestCycle, &worker); + + while (serverSessionController->isConnected()) { + if (serverSessionController->hasRequest()) { + std::wcout << "Received Request!" << std::endl; + worker.pushRequest(serverSessionController->popRequest()); + } + + while (worker.getResponseCollectionSize() > 0) { + std::wcout << "Hand back Response" << std::endl; + serverSessionController->pushResponse(worker.getResponse()); + } + } +} + diff --git a/TabloNode/src/utils/networking.h b/TabloNode/src/utils/network_manager.h similarity index 77% rename from TabloNode/src/utils/networking.h rename to TabloNode/src/utils/network_manager.h index fc35c93..2a83848 100644 --- a/TabloNode/src/utils/networking.h +++ b/TabloNode/src/utils/network_manager.h @@ -1,5 +1,5 @@ -#ifndef NETWORKING_H -#define NETWORKING_H +#ifndef NETWORK_MANAGER_H +#define NETWORK_MANAGER_H #include #include @@ -8,10 +8,10 @@ #include #include -class Networking +class NetworkManager { public: - Networking(std::string interface); + NetworkManager(std::string interface); void handleUdpDiscovery(std::string interface); void handleClientConnection(int serverSocket, int clientSocket); diff --git a/TabloNode/src/utils/networking.cpp b/TabloNode/src/utils/networking.cpp deleted file mode 100644 index e925247..0000000 --- a/TabloNode/src/utils/networking.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "networking.h" - -#include "tabnet.h" - -#include "methods.h" -#include "udp_discovery.h" -#include "worker.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Networking::Networking(std::string interface) { - std::wcout << "Start Socket...." << std::endl; - - std::string containerIP = tabnet::getLocalIpAddress(interface); - - udpThread = std::thread(&Networking::handleUdpDiscovery, this, interface); - - sockaddr_in serverAddress; - serverAddress.sin_family = AF_INET; - serverAddress.sin_port = htons(4004); - serverAddress.sin_addr.s_addr = inet_addr(containerIP.c_str()); - - int serverSocket = socket(AF_INET, SOCK_STREAM, 0); - bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)); - - // On new request: make new worker thread - threadCollection.reserve(100); - listen(serverSocket, 5); - while (true) { - int clientSocket = accept(serverSocket, nullptr, nullptr); - std::wcout << "clientSocket: " << clientSocket << std::endl; - threadCollection.push_back(std::thread(&Networking::handleClientConnection, - this, serverSocket, clientSocket)); - } - - std::wcout << "Terminated!" << std::endl; - - for (auto &socketThread : threadCollection) { - if (socketThread.joinable()) { - socketThread.join(); - } - } - - if (udpThread.joinable()) { - udpThread.join(); - } -} - -void Networking::handleUdpDiscovery(std::string interface) { - UdpDiscovery udpDiscovery(interface); -} - -void Networking::handleClientConnection(int serverSocket, int clientSocket) { - Worker worker; - std::thread workerThread = std::thread(&Worker::solveOrderCycle, &worker); - - // Compleate Handshake - int responseCode = tabnet::sendMessage(clientSocket, Methods::success, ""); - - while (true) { - - // // -> Hand back finished solution - int solutionCollectionSize = worker.getSolutionCollectionSize(); - responseCode = tabnet::sendMessage(clientSocket, Methods::size, std::to_string(solutionCollectionSize)); - tabnet::Packet response = tabnet::receiveMessage(clientSocket); - std::wcout << solutionCollectionSize << "<--- size" << std::endl; - if (response.method == Methods::success) { - for(int index = 0; index < solutionCollectionSize; index++) { - // Send data - tabnet::Packet solution = worker.getSolution(); - std::wcout << "Handing back solution" << solution.method << std::endl; - responseCode = tabnet::sendPacket(clientSocket, solution); - tabnet::Packet response = tabnet::receiveMessage(clientSocket); - if (response.method == Methods::success) { - std::wcout << "Send succeded!" << std::endl; - } else { - std::wcout << "Expected: " << Methods::success << " (success) or " << Methods::failed << " (failed), but got " << response.method << std::endl; - std::wcout << "With following payload" << response.payload.c_str() << std::endl; - } - } - } else if (response.method == Methods::failed) { - std::wcout << "Something went wrong while sending the size! Master response: " << response.payload.c_str() << std::endl; - } else { - std::wcout << "Expected: " << Methods::success << " (success) or " << Methods::failed << " (failed), but got " << response.method << std::endl; - std::wcout << "With following payload" << response.payload.c_str() << std::endl; - } - - responseCode = tabnet::sendMessage(clientSocket, Methods::ready, ""); - - //receive - tabnet::Packet receivedPacket = tabnet::receiveMessage(clientSocket); - if (receivedPacket.method == Methods::size) { - int count = std::stoi(receivedPacket.payload); - if (count != 0) { - responseCode = tabnet::sendMessage(clientSocket, Methods::success, ""); - for(int i = 0; i < count; i++) { - tabnet::Packet order = tabnet::receiveMessage(clientSocket); - worker.pushOrder(order); - responseCode = tabnet::sendMessage(clientSocket, Methods::success, ""); - } - } - } else { - std::wcout << "Expected: " << Methods::size << " (size) got: " << receivedPacket.method << std::endl; - responseCode = tabnet::sendMessage(clientSocket, Methods::failed, "Expected method size"); - } - - // Controlled shutdown of this thread, if the master crashes - if (responseCode < 0) { - std::wcout << "Socket: " << clientSocket << " closed!" << std::endl; - close(clientSocket); - return; - } - } -} diff --git a/TabloNode/src/utils/udp_discovery.cpp b/TabloNode/src/utils/udp_discovery.cpp deleted file mode 100644 index 9d55924..0000000 --- a/TabloNode/src/utils/udp_discovery.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "udp_discovery.h" - -#include "tabnet.h" -#include "methods.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -UdpDiscovery::UdpDiscovery(std::string interface) { - std::wcout << "Start udp discovery..." << std::endl; - - std::string containerIP = tabnet::getLocalIpAddress(interface); - - int udpSocket; - const int port = 4000; - char buffer[1024]; - - udpSocket = socket(AF_INET, SOCK_DGRAM, 0); - if (udpSocket < 0) { - std::wcout << "Create socket failed!" << std::endl; - return; - } - - int broadcast = 1; - setsockopt(udpSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); - - sockaddr_in nodeAddress{}; - nodeAddress.sin_family = AF_INET; - nodeAddress.sin_addr.s_addr = htonl(INADDR_ANY); - nodeAddress.sin_port = htons(port); - - if (bind(udpSocket, (struct sockaddr*)&nodeAddress, sizeof(nodeAddress)) < 0) { - std::wcout << "UDP Socket bind failed!" << std::endl; - return; - } - std::wcout << "Listening on UDP port " << port << std::endl; - while (true) { - // Get UDP Discovery packet - tabnet::Packet masterIP = tabnet::receiveMessage(udpSocket); - if (masterIP.method == Methods::ip) { - if (masterIP.payload.length() != 0 && tabnet::isValidIpV4(masterIP.payload)) { - // DEBUG ONLY: - //std::wcout << masterIP.c_str() << std::endl; - - // Send response over TCP - int recieveSocket = 0; - struct sockaddr_in masterAddress; - masterAddress.sin_family = AF_INET; - masterAddress.sin_port = htons(4001); - - if ((recieveSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - std::wcout << "Socket creation error" << std::endl; - continue; - } - if (inet_pton(AF_INET, masterIP.payload.c_str(), &masterAddress.sin_addr) <= 0) { - std::wcout << "Address not supported" << std::endl; - continue; - } - if (connect(recieveSocket, (struct sockaddr*)&masterAddress, sizeof(masterAddress)) < 0) { - std::wcout << "Connection failed" << std::endl; - continue; - } - //send(recieveSocket, containerIP.c_str(), containerIP.size(), 0); - tabnet::sendMessage(recieveSocket, Methods::ip, containerIP.c_str()); - close(recieveSocket); - } else { - std::wcout << "Invalid ip!" << std::endl; - } - } else { - std::wcout << "Expected" << Methods::ip << " (ip) but got: " << masterIP.method << std::endl; - } - } - close(udpSocket); -} - diff --git a/TabloNode/src/utils/udp_discovery.h b/TabloNode/src/utils/udp_discovery.h deleted file mode 100644 index 62dde08..0000000 --- a/TabloNode/src/utils/udp_discovery.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UDP_DISCOVERY_H -#define UDP_DISCOVERY_H - -#include - -class UdpDiscovery -{ - public: - UdpDiscovery(std::string interface); -}; - -#endif diff --git a/TabloNode/src/utils/worker.cpp b/TabloNode/src/utils/worker.cpp index 9402e63..22462b9 100644 --- a/TabloNode/src/utils/worker.cpp +++ b/TabloNode/src/utils/worker.cpp @@ -1,37 +1,31 @@ - #include "worker.h" -#include +#include +#include "csv_manager.h" + +#include #include #include - -#include "tabnet.h" -#include "methods.h" +#include // Cycle -void Worker::solveOrderCycle() { +void Worker::solveRequestCycle() { while (true) { - int orderSize = getOrderCollectionSize(); - if (orderSize > 0) { - for (int count; count < orderSize; count++) { - tabnet::Packet order = getOrder(); - - switch (order.method) { - case Methods::test: - std::wcout << "TEST!" << std::endl; - pushSolution(Worker::test(order)); - break; - - case Methods::setFile: - pushSolution(Worker::setFile(order)); - break; + int requestSize = getRequestCollectionSize(); + if (requestSize > 0) { + for (int count = 0; count < requestSize; count++) { + ttp2::ServerSessionController::Packet request = getRequest(); - case Methods::empty: - break; - - default: - std::wcout << "Unknown action: " << order.method << " -> Expected a method between " << Methods::START << " and " << Methods::END << std::endl; - break; + if (std::holds_alternative(request.payload)) { + pushResponse(Worker::test(request)); + } else if (std::holds_alternative(request.payload)) { + ttp2::ServerSessionController::File file = std::get(request.payload); + Worker::setFile(file); + } else if (std::holds_alternative(request.payload)) { + ttp2::ServerSessionController::Viewport viewportRequest = std::get(request.payload); + pushResponse(Worker::getViewport(viewportRequest)); + } else { + std::wcout << "Unknown payload type!" << std::endl; } } } @@ -39,57 +33,70 @@ void Worker::solveOrderCycle() { } // Logic functions -tabnet::Packet Worker::test(tabnet::Packet packet) { - tabnet::Packet solution; - solution.method = Methods::response; - solution.payload = packet.payload; - return solution; +ttp2::ServerSessionController::Packet Worker::test(ttp2::ServerSessionController::Packet packet) { + return packet; +} + +void Worker::setFile(ttp2::ServerSessionController::File newFile) { + CsvManager newCsvManager; + newCsvManager.setFile(newFile); + this->csvManager = newCsvManager; } -tabnet::Packet Worker::setFile(tabnet::Packet packet) { +ttp2::ServerSessionController::Packet Worker::getViewport(ttp2::ServerSessionController::Viewport viewportRequest) { + ttp2::ServerSessionController::Packet packet; + + if (viewportRequest.xEnd < viewportRequest.xStart || viewportRequest.yEnd < viewportRequest.yStart) { + ttp2::ServerSessionController::Viewport emptyViewport; + packet.payload = emptyViewport; + return packet; + } + + viewportRequest.payload = this->csvManager.getViewport(viewportRequest.xStart, viewportRequest.xEnd, + viewportRequest.yStart, viewportRequest.yEnd); + packet.payload = viewportRequest; return packet; } // Service logic -tabnet::Packet Worker::getOrder() { +ttp2::ServerSessionController::Packet Worker::getRequest() { std::lock_guard lock(mtx); - if (!orders.empty()) { - tabnet::Packet firstOrder = orders[0]; - orders.erase(orders.begin()); - return firstOrder; + if (!requests.empty()) { + ttp2::ServerSessionController::Packet firstRequest = requests[0]; + requests.erase(requests.begin()); + return firstRequest; } - tabnet::Packet emptyPacket; - emptyPacket.method = Methods::empty; + ttp2::ServerSessionController::Packet emptyPacket; return emptyPacket; } -void Worker::pushOrder(tabnet::Packet packet) { +void Worker::pushRequest(ttp2::ServerSessionController::Packet packet) { std::lock_guard lock(mtx); - orders.push_back(packet); + requests.push_back(packet); } -tabnet::Packet Worker::getSolution() { +ttp2::ServerSessionController::Packet Worker::getResponse() { std::lock_guard lock(mtx); - if (!solutions.empty()) { - tabnet::Packet firstSolution = solutions[0]; - solutions.erase(solutions.begin()); - return firstSolution; + if (!responses.empty()) { + ttp2::ServerSessionController::Packet firstResponse = responses[0]; + responses.erase(responses.begin()); + return firstResponse; } - tabnet::Packet emptyPacket; + ttp2::ServerSessionController::Packet emptyPacket; return emptyPacket; } -void Worker::pushSolution(tabnet::Packet packet) { +void Worker::pushResponse(ttp2::ServerSessionController::Packet packet) { std::lock_guard lock(mtx); - solutions.push_back(packet); + responses.push_back(packet); } -int Worker::getSolutionCollectionSize() { +int Worker::getResponseCollectionSize() { std::lock_guard lock(mtx); - return solutions.size(); + return responses.size(); } -int Worker::getOrderCollectionSize() { +int Worker::getRequestCollectionSize() { std::lock_guard lock(mtx); - return orders.size(); + return requests.size(); } diff --git a/TabloNode/src/utils/worker.h b/TabloNode/src/utils/worker.h index 06e5cca..36a481c 100644 --- a/TabloNode/src/utils/worker.h +++ b/TabloNode/src/utils/worker.h @@ -1,35 +1,39 @@ #ifndef WORKER_H #define WORKER_H +#include +#include "csv_manager.h" + #include #include -#include "tabnet.h" - class Worker { public: // Cycle - void solveOrderCycle(); - - // Logic functions - tabnet::Packet test(tabnet::Packet packet); - tabnet::Packet setFile(tabnet::Packet packet); + void solveRequestCycle(); // Service logic - tabnet::Packet getOrder(); - void pushOrder(tabnet::Packet packet); + ttp2::ServerSessionController::Packet getRequest(); + void pushRequest(ttp2::ServerSessionController::Packet packet); - tabnet::Packet getSolution(); - void pushSolution(tabnet::Packet packet); + ttp2::ServerSessionController::Packet getResponse(); + void pushResponse(ttp2::ServerSessionController::Packet packet); - int getSolutionCollectionSize(); - int getOrderCollectionSize(); + int getResponseCollectionSize(); + int getRequestCollectionSize(); private: std::mutex mtx; - std::vector solutions; - std::vector orders; + std::vector responses; + std::vector requests; + + CsvManager csvManager; + + // Logic functions + ttp2::ServerSessionController::Packet test(ttp2::ServerSessionController::Packet packet); + void setFile(ttp2::ServerSessionController::File newFile); + ttp2::ServerSessionController::Packet getViewport(ttp2::ServerSessionController::Viewport viewportRequest); }; #endif diff --git a/build-proto.sh b/build-proto.sh deleted file mode 100755 index 31cdfcb..0000000 --- a/build-proto.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -protoc --cpp_out=./ lib/libtabnet/src/protobuf/transfer_protocol.proto diff --git a/flake.lock b/flake.lock index fdb023c..ba113fc 100644 --- a/flake.lock +++ b/flake.lock @@ -16,9 +16,79 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1774386573, + "narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1780243769, + "narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "331800de5053fcebacf6813adb5db9c9dca22a0c", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "ttp2": "ttp2", + "tud": "tud" + } + }, + "ttp2": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1781285548, + "narHash": "sha256-AWF1w1671jd/K4Pfi72NwkudRRkuoZJl1VuxzYYTQ4I=", + "owner": "Sobottasgithub", + "repo": "ttp2", + "rev": "5b6b6864d3fce60a47337956e2a7c61d2b98d704", + "type": "github" + }, + "original": { + "owner": "Sobottasgithub", + "repo": "ttp2", + "type": "github" + } + }, + "tud": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1780684021, + "narHash": "sha256-XucbF/32EUSvk8Of0ZIRc5cj/zDgoVwW57MK1z8ibmQ=", + "owner": "Sobottasgithub", + "repo": "tud", + "rev": "640a87ee87f1c761b6be7451094e64c274c6900c", + "type": "github" + }, + "original": { + "owner": "Sobottasgithub", + "repo": "tud", + "type": "github" } } }, diff --git a/flake.nix b/flake.nix index b0f0a9c..f37abbd 100644 --- a/flake.nix +++ b/flake.nix @@ -3,72 +3,211 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + + ttp2 = { + url = "github:Sobottasgithub/ttp2"; + }; + + tud = { + url = "github:Sobottasgithub/tud"; + }; }; outputs = - { self, nixpkgs }: + { + self, + nixpkgs, + ttp2, + tud, + }: let system = "x86_64-linux"; - pkgs = import nixpkgs { inherit system; }; - version = "1.2"; + pkgs = import nixpkgs { + inherit system; + }; + + version = "1.3"; + + libttp2 = ttp2.packages.${system}.lib; + libtud = tud.packages.${system}.lib; packages = with pkgs; [ cmake gcc gnumake protobuf + libttp2 + libtud ]; in { - packages.${system} = let - tablo-full = pkgs.stdenv.mkDerivation { + mkTabloPackage = + { + pname, + buildTarget ? pname, + + enableLibtabcrypt ? false, + enableLibtabnet ? false, + + enableNode ? false, + enableClient ? false, + enableMaster ? false, + + extraInputs ? [ ], + }: + pkgs.stdenv.mkDerivation { + inherit pname version; + + src = ./.; + + meta = { + description = "${pname} package"; + mainProgram = pname; + }; + + buildInputs = packages ++ extraInputs; + + configurePhase = '' + cmake -B build -S $src \ + -DCMAKE_BUILD_TYPE=Release \ + -DDEF_LIBTABCRYPT=${if enableLibtabcrypt then "ON" else "OFF"} \ + -DDEF_LIBTABNET=${if enableLibtabnet then "ON" else "OFF"} \ + -DDEF_NODE=${if enableNode then "ON" else "OFF"} \ + -DDEF_CLIENT=${if enableClient then "ON" else "OFF"} \ + -DDEF_MASTER=${if enableMaster then "ON" else "OFF"} + ''; + + buildPhase = '' + cmake --build build \ + --target ${buildTarget} \ + -j$NIX_BUILD_CORES + ''; + + installPhase = '' + cmake --install build --prefix=$out + cp LICENSE $out/ + ''; + }; + + libtabcrypt = mkTabloPackage { + pname = "libtabcrypt"; + buildTarget = "tabcrypt"; + + enableLibtabcrypt = true; + }; + + libtabnet = mkTabloPackage { + pname = "libtabnet"; + buildTarget = "tabnet"; + + enableLibtabnet = true; + + extraInputs = [ + libtabcrypt + # include libttp2 just here for later setup! + ]; + }; + + tablo-node = mkTabloPackage { + pname = "tablo-node"; + + enableNode = true; + + extraInputs = [ + libtabcrypt + libtabnet + ]; + }; + + tablo-client = mkTabloPackage { + pname = "tablo-client"; + + enableClient = true; + enableLibtabcrypt = true; + enableLibtabnet = true; + + extraInputs = [ + libtabcrypt + libtabnet + ]; + }; + + tablo-master = mkTabloPackage { + pname = "tablo-master"; + + enableMaster = true; + enableLibtabcrypt = true; + enableLibtabnet = true; + + extraInputs = [ + libtabcrypt + libtabnet + ]; + }; + + tablo-full = mkTabloPackage { pname = "tablo-full"; - inherit version; - src = ./.; + buildTarget = "all"; - meta = { - description = "Full tablo package"; - mainProgram = "tablo-node"; - }; + enableLibtabcrypt = true; + enableLibtabnet = true; - buildInputs = packages; + enableNode = true; + enableClient = true; + enableMaster = true; - configurePhase = '' - cmake -B build -S $src -DCMAKE_BUILD_TYPE=Release - ''; + extraInputs = [ + libtabcrypt + libtabnet + ]; + }; - buildPhase = '' - cmake --build build - ''; + tablo = pkgs.symlinkJoin { + name = "tablo-${version}"; - installPhase = '' - cmake --install build --prefix=$out - cp LICENSE $out/ - ''; + paths = [ + libtabcrypt + libtabnet + tablo-node + tablo-client + tablo-master + ]; }; mkTabloDocker = - name: extraConfig: + package: binary: pkgs.dockerTools.buildImage { - inherit name; + name = binary; tag = version; + config = { - Cmd = [ "${tablo-full}/bin/${name}" ]; - } - // extraConfig; + Cmd = [ "${package}/bin/${binary}" ]; + }; }; in { - inherit tablo-full; - default = tablo-full; - tablo-node-docker = mkTabloDocker "tablo-node" { }; - tablo-master-docker = mkTabloDocker "tablo-master" { }; + inherit + tablo + tablo-node + tablo-client + tablo-master + tablo-full + libtabcrypt + libtabnet + libttp2 + libtud + ; + + default = tablo; - # used for client containers not deployed via swarm - tablo-client-docker = mkTabloDocker "tablo-client" { }; + tablo-node-docker = mkTabloDocker tablo-node "tablo-node"; + + tablo-master-docker = mkTabloDocker tablo-master "tablo-master"; + + tablo-client-docker = mkTabloDocker tablo-client "tablo-client"; }; devShells.${system}.default = @@ -82,13 +221,14 @@ pkgs.mkShell { packages = devPackages; - inputsFrom = [ self.packages.${system}.default ]; + inputsFrom = [ + self.packages.${system}.default + ]; shellHook = '' git status cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ''; }; - }; } diff --git a/lib/libtabnet/CMakeLists.txt b/lib/libtabnet/CMakeLists.txt index e142c7c..a5573f2 100644 --- a/lib/libtabnet/CMakeLists.txt +++ b/lib/libtabnet/CMakeLists.txt @@ -4,39 +4,14 @@ project(tabnet) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# find_library(protobuf protobuf) - -find_package(protobuf REQUIRED) - -include_directories( - include - ${Protobuf_INCLUDE_DIRS} -) +include_directories(include) file(GLOB_RECURSE SOURCES "src/*.cpp") # file(GLOB_RECURSE HEADERS "include/*.h") -set(PROTO_FILES - src/protobuf/transfer_protocol.proto -) - -add_library(tabnet SHARED ${SOURCES} ${PROTO_SRCS}) - -protobuf_generate( - TARGET tabnet - LANGUAGE cpp - OUT_VAR PROTO_SRCS - PROTOS ${PROTO_FILES} -) - -target_include_directories(tabnet PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR} # for protobuf -) - -# Link against the tabcrypt and protobuf library -target_link_libraries(tabnet PRIVATE tabcrypt protobuf::libprotobuf) +add_library(tabnet SHARED ${SOURCES}) + +target_include_directories(tabnet PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) install(TARGETS tabnet DESTINATION lib) install(DIRECTORY include/ DESTINATION include) diff --git a/lib/libtabnet/include/methods.h b/lib/libtabnet/include/methods.h deleted file mode 100644 index a387722..0000000 --- a/lib/libtabnet/include/methods.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef METHODS_H -#define METHODS_H - -enum Methods { - empty = 10, - success = 100, - ready = 110, - failed = 200, - ip = 300, - - START = 400, - test = 401, - size = 402, - response = 403, - setFile = 404, - END -}; - -#endif diff --git a/lib/libtabnet/include/tabnet.h b/lib/libtabnet/include/tabnet.h index 4c73827..4397666 100644 --- a/lib/libtabnet/include/tabnet.h +++ b/lib/libtabnet/include/tabnet.h @@ -1,24 +1,6 @@ #ifndef libtabnet #define libtabnet -#include -#include -#include - -namespace tabnet { - struct Packet { - int method; - std::string payload; - }; - - std::string getLocalIpAddress(std::string interface); - std::string getBroadcastIpAddress(); - int sendMessage(int socket, int method, std::string payload); - int sendPacket(int socket, tabnet::Packet packet); - int sendMessageTo(int socket, const sockaddr_in& broadcast, int method, std::string payload); - Packet receiveMessage(int socket); - bool isValidIpV4(std::string &ipString); - bool isNumeric(const std::string& string); -} +namespace tabnet {} #endif diff --git a/lib/libtabnet/src/protobuf/transfer_protocol.pb.cc b/lib/libtabnet/src/protobuf/transfer_protocol.pb.cc deleted file mode 100644 index 1b8c9e5..0000000 --- a/lib/libtabnet/src/protobuf/transfer_protocol.pb.cc +++ /dev/null @@ -1,397 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// NO CHECKED-IN PROTOBUF GENCODE -// source: lib/libtabnet/src/protobuf/transfer_protocol.proto -// Protobuf C++ Version: 6.31.1 - -#include "lib/libtabnet/src/protobuf/transfer_protocol.pb.h" - -#include -#include -#include "google/protobuf/io/coded_stream.h" -#include "google/protobuf/generated_message_tctable_impl.h" -#include "google/protobuf/extension_set.h" -#include "google/protobuf/generated_message_util.h" -#include "google/protobuf/wire_format_lite.h" -#include "google/protobuf/descriptor.h" -#include "google/protobuf/generated_message_reflection.h" -#include "google/protobuf/reflection_ops.h" -#include "google/protobuf/wire_format.h" -// @@protoc_insertion_point(includes) - -// Must be included last. -#include "google/protobuf/port_def.inc" -PROTOBUF_PRAGMA_INIT_SEG -namespace _pb = ::google::protobuf; -namespace _pbi = ::google::protobuf::internal; -namespace _fl = ::google::protobuf::internal::field_layout; -namespace transferprotocol { - -inline constexpr SerializedPacket::Impl_::Impl_( - ::_pbi::ConstantInitialized) noexcept - : _cached_size_{0}, - payload_( - &::google::protobuf::internal::fixed_address_empty_string, - ::_pbi::ConstantInitialized()), - method_{0} {} - -template -PROTOBUF_CONSTEXPR SerializedPacket::SerializedPacket(::_pbi::ConstantInitialized) -#if defined(PROTOBUF_CUSTOM_VTABLE) - : ::google::protobuf::Message(SerializedPacket_class_data_.base()), -#else // PROTOBUF_CUSTOM_VTABLE - : ::google::protobuf::Message(), -#endif // PROTOBUF_CUSTOM_VTABLE - _impl_(::_pbi::ConstantInitialized()) { -} -struct SerializedPacketDefaultTypeInternal { - PROTOBUF_CONSTEXPR SerializedPacketDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} - ~SerializedPacketDefaultTypeInternal() {} - union { - SerializedPacket _instance; - }; -}; - -PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SerializedPacketDefaultTypeInternal _SerializedPacket_default_instance_; -} // namespace transferprotocol -static constexpr const ::_pb::EnumDescriptor *PROTOBUF_NONNULL *PROTOBUF_NULLABLE - file_level_enum_descriptors_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto = nullptr; -static constexpr const ::_pb::ServiceDescriptor *PROTOBUF_NONNULL *PROTOBUF_NULLABLE - file_level_service_descriptors_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto = nullptr; -const ::uint32_t - TableStruct_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE( - protodesc_cold) = { - 0x081, // bitmap - PROTOBUF_FIELD_OFFSET(::transferprotocol::SerializedPacket, _impl_._has_bits_), - 5, // hasbit index offset - PROTOBUF_FIELD_OFFSET(::transferprotocol::SerializedPacket, _impl_.method_), - PROTOBUF_FIELD_OFFSET(::transferprotocol::SerializedPacket, _impl_.payload_), - 1, - 0, -}; - -static const ::_pbi::MigrationSchema - schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { - {0, sizeof(::transferprotocol::SerializedPacket)}, -}; -static const ::_pb::Message* PROTOBUF_NONNULL const file_default_instances[] = { - &::transferprotocol::_SerializedPacket_default_instance_._instance, -}; -const char descriptor_table_protodef_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE( - protodesc_cold) = { - "\n2lib/libtabnet/src/protobuf/transfer_pr" - "otocol.proto\022\020transferprotocol\"3\n\020Serial" - "izedPacket\022\016\n\006method\030\001 \001(\005\022\017\n\007payload\030\002 " - "\001(\tb\010editionsp\350\007" -}; -static ::absl::once_flag descriptor_table_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto_once; -PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto = { - false, - false, - 136, - descriptor_table_protodef_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto, - "lib/libtabnet/src/protobuf/transfer_protocol.proto", - &descriptor_table_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto_once, - nullptr, - 0, - 1, - schemas, - file_default_instances, - TableStruct_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto::offsets, - file_level_enum_descriptors_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto, - file_level_service_descriptors_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto, -}; -namespace transferprotocol { -// =================================================================== - -class SerializedPacket::_Internal { - public: - using HasBits = - decltype(::std::declval()._impl_._has_bits_); - static constexpr ::int32_t kHasBitsOffset = - 8 * PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_._has_bits_); -}; - -SerializedPacket::SerializedPacket(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) -#if defined(PROTOBUF_CUSTOM_VTABLE) - : ::google::protobuf::Message(arena, SerializedPacket_class_data_.base()) { -#else // PROTOBUF_CUSTOM_VTABLE - : ::google::protobuf::Message(arena) { -#endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); - // @@protoc_insertion_point(arena_constructor:transferprotocol.SerializedPacket) -} -PROTOBUF_NDEBUG_INLINE SerializedPacket::Impl_::Impl_( - ::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from, - const ::transferprotocol::SerializedPacket& from_msg) - : _has_bits_{from._has_bits_}, - _cached_size_{0}, - payload_(arena, from.payload_) {} - -SerializedPacket::SerializedPacket( - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, - const SerializedPacket& from) -#if defined(PROTOBUF_CUSTOM_VTABLE) - : ::google::protobuf::Message(arena, SerializedPacket_class_data_.base()) { -#else // PROTOBUF_CUSTOM_VTABLE - : ::google::protobuf::Message(arena) { -#endif // PROTOBUF_CUSTOM_VTABLE - SerializedPacket* const _this = this; - (void)_this; - _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>( - from._internal_metadata_); - new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from); - _impl_.method_ = from._impl_.method_; - - // @@protoc_insertion_point(copy_constructor:transferprotocol.SerializedPacket) -} -PROTOBUF_NDEBUG_INLINE SerializedPacket::Impl_::Impl_( - ::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) - : _cached_size_{0}, - payload_(arena) {} - -inline void SerializedPacket::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.method_ = {}; -} -SerializedPacket::~SerializedPacket() { - // @@protoc_insertion_point(destructor:transferprotocol.SerializedPacket) - SharedDtor(*this); -} -inline void SerializedPacket::SharedDtor(MessageLite& self) { - SerializedPacket& this_ = static_cast(self); - this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>(); - ABSL_DCHECK(this_.GetArena() == nullptr); - this_._impl_.payload_.Destroy(); - this_._impl_.~Impl_(); -} - -inline void* PROTOBUF_NONNULL SerializedPacket::PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { - return ::new (mem) SerializedPacket(arena); -} -constexpr auto SerializedPacket::InternalNewImpl_() { - return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(SerializedPacket), - alignof(SerializedPacket)); -} -constexpr auto SerializedPacket::InternalGenerateClassData_() { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &_SerializedPacket_default_instance_._instance, - &_table_.header, - nullptr, // OnDemandRegisterArenaDtor - nullptr, // IsInitialized - &SerializedPacket::MergeImpl, - ::google::protobuf::Message::GetNewImpl(), -#if defined(PROTOBUF_CUSTOM_VTABLE) - &SerializedPacket::SharedDtor, - ::google::protobuf::Message::GetClearImpl(), &SerializedPacket::ByteSizeLong, - &SerializedPacket::_InternalSerialize, -#endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_._cached_size_), - false, - }, - &SerializedPacket::kDescriptorMethods, - &descriptor_table_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto, - nullptr, // tracker - }; -} - -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull SerializedPacket_class_data_ = - SerializedPacket::InternalGenerateClassData_(); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -SerializedPacket::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&SerializedPacket_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(SerializedPacket_class_data_.tc_table); - return SerializedPacket_class_data_.base(); -} -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 -const ::_pbi::TcParseTable<1, 2, 0, 49, 2> -SerializedPacket::_table_ = { - { - PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_._has_bits_), - 0, // no _extensions_ - 2, 8, // max_field_number, fast_idx_mask - offsetof(decltype(_table_), field_lookup_table), - 4294967292, // skipmap - offsetof(decltype(_table_), field_entries), - 2, // num_field_entries - 0, // num_aux_entries - offsetof(decltype(_table_), field_names), // no aux_entries - SerializedPacket_class_data_.base(), - nullptr, // post_loop_handler - ::_pbi::TcParser::GenericFallback, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::transferprotocol::SerializedPacket>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE - }, {{ - // string payload = 2; - {::_pbi::TcParser::FastUS1, - {18, 0, 0, PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_.payload_)}}, - // int32 method = 1; - {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(SerializedPacket, _impl_.method_), 1>(), - {8, 1, 0, PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_.method_)}}, - }}, {{ - 65535, 65535 - }}, {{ - // int32 method = 1; - {PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_.method_), _Internal::kHasBitsOffset + 1, 0, - (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, - // string payload = 2; - {PROTOBUF_FIELD_OFFSET(SerializedPacket, _impl_.payload_), _Internal::kHasBitsOffset + 0, 0, - (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)}, - }}, - // no aux_entries - {{ - "\41\0\7\0\0\0\0\0" - "transferprotocol.SerializedPacket" - "payload" - }}, -}; -PROTOBUF_NOINLINE void SerializedPacket::Clear() { -// @@protoc_insertion_point(message_clear_start:transferprotocol.SerializedPacket) - ::google::protobuf::internal::TSanWrite(&_impl_); - ::uint32_t cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void) cached_has_bits; - - cached_has_bits = _impl_._has_bits_[0]; - if ((cached_has_bits & 0x00000001u) != 0) { - _impl_.payload_.ClearNonDefaultToEmpty(); - } - _impl_.method_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); -} - -#if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL SerializedPacket::_InternalSerialize( - const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { - const SerializedPacket& this_ = static_cast(base); -#else // PROTOBUF_CUSTOM_VTABLE -::uint8_t* PROTOBUF_NONNULL SerializedPacket::_InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - const SerializedPacket& this_ = *this; -#endif // PROTOBUF_CUSTOM_VTABLE - // @@protoc_insertion_point(serialize_to_array_start:transferprotocol.SerializedPacket) - ::uint32_t cached_has_bits = 0; - (void)cached_has_bits; - - cached_has_bits = this_._impl_._has_bits_[0]; - // int32 method = 1; - if ((cached_has_bits & 0x00000002u) != 0) { - target = - ::google::protobuf::internal::WireFormatLite::WriteInt32ToArrayWithField<1>( - stream, this_._internal_method(), target); - } - - // string payload = 2; - if ((cached_has_bits & 0x00000001u) != 0) { - const ::std::string& _s = this_._internal_payload(); - ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "transferprotocol.SerializedPacket.payload"); - target = stream->WriteStringMaybeAliased(2, _s, target); - } - - if (ABSL_PREDICT_FALSE(this_._internal_metadata_.have_unknown_fields())) { - target = - ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray( - this_._internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream); - } - // @@protoc_insertion_point(serialize_to_array_end:transferprotocol.SerializedPacket) - return target; -} - -#if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t SerializedPacket::ByteSizeLong(const MessageLite& base) { - const SerializedPacket& this_ = static_cast(base); -#else // PROTOBUF_CUSTOM_VTABLE -::size_t SerializedPacket::ByteSizeLong() const { - const SerializedPacket& this_ = *this; -#endif // PROTOBUF_CUSTOM_VTABLE - // @@protoc_insertion_point(message_byte_size_start:transferprotocol.SerializedPacket) - ::size_t total_size = 0; - - ::uint32_t cached_has_bits = 0; - // Prevent compiler warnings about cached_has_bits being unused - (void)cached_has_bits; - - ::_pbi::Prefetch5LinesFrom7Lines(&this_); - cached_has_bits = this_._impl_._has_bits_[0]; - if ((cached_has_bits & 0x00000003u) != 0) { - // string payload = 2; - if ((cached_has_bits & 0x00000001u) != 0) { - total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( - this_._internal_payload()); - } - // int32 method = 1; - if ((cached_has_bits & 0x00000002u) != 0) { - total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( - this_._internal_method()); - } - } - return this_.MaybeComputeUnknownFieldsSize(total_size, - &this_._impl_._cached_size_); -} - -void SerializedPacket::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { - auto* const _this = static_cast(&to_msg); - auto& from = static_cast(from_msg); - // @@protoc_insertion_point(class_specific_merge_from_start:transferprotocol.SerializedPacket) - ABSL_DCHECK_NE(&from, _this); - ::uint32_t cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._impl_._has_bits_[0]; - if ((cached_has_bits & 0x00000003u) != 0) { - if ((cached_has_bits & 0x00000001u) != 0) { - _this->_internal_set_payload(from._internal_payload()); - } - if ((cached_has_bits & 0x00000002u) != 0) { - _this->_impl_.method_ = from._impl_.method_; - } - } - _this->_impl_._has_bits_[0] |= cached_has_bits; - _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); -} - -void SerializedPacket::CopyFrom(const SerializedPacket& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:transferprotocol.SerializedPacket) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - - -void SerializedPacket::InternalSwap(SerializedPacket* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { - using ::std::swap; - auto* arena = GetArena(); - ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.payload_, &other->_impl_.payload_, arena); - swap(_impl_.method_, other->_impl_.method_); -} - -::google::protobuf::Metadata SerializedPacket::GetMetadata() const { - return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full()); -} -// @@protoc_insertion_point(namespace_scope) -} // namespace transferprotocol -namespace google { -namespace protobuf { -} // namespace protobuf -} // namespace google -// @@protoc_insertion_point(global_scope) -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type - _static_init2_ [[maybe_unused]] = - (::_pbi::AddDescriptors(&descriptor_table_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto), - ::std::false_type{}); -#include "google/protobuf/port_undef.inc" diff --git a/lib/libtabnet/src/protobuf/transfer_protocol.pb.h b/lib/libtabnet/src/protobuf/transfer_protocol.pb.h deleted file mode 100644 index 7e412c7..0000000 --- a/lib/libtabnet/src/protobuf/transfer_protocol.pb.h +++ /dev/null @@ -1,407 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// NO CHECKED-IN PROTOBUF GENCODE -// source: lib/libtabnet/src/protobuf/transfer_protocol.proto -// Protobuf C++ Version: 6.31.1 - -#ifndef lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto_2epb_2eh -#define lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto_2epb_2eh - -#include -#include -#include -#include - -#include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 6031001 -#error "Protobuf C++ gencode is built with an incompatible version of" -#error "Protobuf C++ headers/runtime. See" -#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" -#endif -#include "google/protobuf/io/coded_stream.h" -#include "google/protobuf/arena.h" -#include "google/protobuf/arenastring.h" -#include "google/protobuf/generated_message_tctable_decl.h" -#include "google/protobuf/generated_message_util.h" -#include "google/protobuf/metadata_lite.h" -#include "google/protobuf/generated_message_reflection.h" -#include "google/protobuf/message.h" -#include "google/protobuf/message_lite.h" -#include "google/protobuf/repeated_field.h" // IWYU pragma: export -#include "google/protobuf/extension_set.h" // IWYU pragma: export -#include "google/protobuf/unknown_field_set.h" -// @@protoc_insertion_point(includes) - -// Must be included last. -#include "google/protobuf/port_def.inc" - -#define PROTOBUF_INTERNAL_EXPORT_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto - -namespace google { -namespace protobuf { -namespace internal { -template -::absl::string_view GetAnyMessageName(); -} // namespace internal -} // namespace protobuf -} // namespace google - -// Internal implementation detail -- do not use these members. -struct TableStruct_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto { - static const ::uint32_t offsets[]; -}; -extern "C" { -extern const ::google::protobuf::internal::DescriptorTable descriptor_table_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto; -} // extern "C" -namespace transferprotocol { -class SerializedPacket; -struct SerializedPacketDefaultTypeInternal; -extern SerializedPacketDefaultTypeInternal _SerializedPacket_default_instance_; -extern const ::google::protobuf::internal::ClassDataFull SerializedPacket_class_data_; -} // namespace transferprotocol -namespace google { -namespace protobuf { -} // namespace protobuf -} // namespace google - -namespace transferprotocol { - -// =================================================================== - - -// ------------------------------------------------------------------- - -class SerializedPacket final : public ::google::protobuf::Message -/* @@protoc_insertion_point(class_definition:transferprotocol.SerializedPacket) */ { - public: - inline SerializedPacket() : SerializedPacket(nullptr) {} - ~SerializedPacket() PROTOBUF_FINAL; - -#if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(SerializedPacket* PROTOBUF_NONNULL msg, std::destroying_delete_t) { - SharedDtor(*msg); - ::google::protobuf::internal::SizedDelete(msg, sizeof(SerializedPacket)); - } -#endif - - template - explicit PROTOBUF_CONSTEXPR SerializedPacket(::google::protobuf::internal::ConstantInitialized); - - inline SerializedPacket(const SerializedPacket& from) : SerializedPacket(nullptr, from) {} - inline SerializedPacket(SerializedPacket&& from) noexcept - : SerializedPacket(nullptr, ::std::move(from)) {} - inline SerializedPacket& operator=(const SerializedPacket& from) { - CopyFrom(from); - return *this; - } - inline SerializedPacket& operator=(SerializedPacket&& from) noexcept { - if (this == &from) return *this; - if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); - } else { - CopyFrom(from); - } - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const - ABSL_ATTRIBUTE_LIFETIME_BOUND { - return _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance); - } - inline ::google::protobuf::UnknownFieldSet* PROTOBUF_NONNULL mutable_unknown_fields() - ABSL_ATTRIBUTE_LIFETIME_BOUND { - return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); - } - - static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { - return GetDescriptor(); - } - static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL GetDescriptor() { - return default_instance().GetMetadata().descriptor; - } - static const ::google::protobuf::Reflection* PROTOBUF_NONNULL GetReflection() { - return default_instance().GetMetadata().reflection; - } - static const SerializedPacket& default_instance() { - return *reinterpret_cast( - &_SerializedPacket_default_instance_); - } - static constexpr int kIndexInFileMessages = 0; - friend void swap(SerializedPacket& a, SerializedPacket& b) { a.Swap(&b); } - inline void Swap(SerializedPacket* PROTOBUF_NONNULL other) { - if (other == this) return; - if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); - } else { - ::google::protobuf::internal::GenericSwap(this, other); - } - } - void UnsafeArenaSwap(SerializedPacket* PROTOBUF_NONNULL other) { - if (other == this) return; - ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); - } - - // implements Message ---------------------------------------------- - - SerializedPacket* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { - return ::google::protobuf::Message::DefaultConstruct(arena); - } - using ::google::protobuf::Message::CopyFrom; - void CopyFrom(const SerializedPacket& from); - using ::google::protobuf::Message::MergeFrom; - void MergeFrom(const SerializedPacket& from) { SerializedPacket::MergeImpl(*this, from); } - - private: - static void MergeImpl(::google::protobuf::MessageLite& to_msg, - const ::google::protobuf::MessageLite& from_msg); - - public: - bool IsInitialized() const { - return true; - } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; - #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); - } - #else // PROTOBUF_CUSTOM_VTABLE - ::size_t ByteSizeLong() const final; - ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; - #endif // PROTOBUF_CUSTOM_VTABLE - int GetCachedSize() const { return _impl_._cached_size_.Get(); } - - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(SerializedPacket* PROTOBUF_NONNULL other); - private: - template - friend ::absl::string_view(::google::protobuf::internal::GetAnyMessageName)(); - static ::absl::string_view FullMessageName() { return "transferprotocol.SerializedPacket"; } - - protected: - explicit SerializedPacket(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - SerializedPacket(::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const SerializedPacket& from); - SerializedPacket( - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, SerializedPacket&& from) noexcept - : SerializedPacket(arena) { - *this = ::std::move(from); - } - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); - - public: - static constexpr auto InternalGenerateClassData_(); - - ::google::protobuf::Metadata GetMetadata() const; - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - enum : int { - kPayloadFieldNumber = 2, - kMethodFieldNumber = 1, - }; - // string payload = 2; - bool has_payload() const; - void clear_payload() ; - const ::std::string& payload() const; - template - void set_payload(Arg_&& arg, Args_... args); - ::std::string* PROTOBUF_NONNULL mutable_payload(); - [[nodiscard]] ::std::string* PROTOBUF_NULLABLE release_payload(); - void set_allocated_payload(::std::string* PROTOBUF_NULLABLE value); - - private: - const ::std::string& _internal_payload() const; - PROTOBUF_ALWAYS_INLINE void _internal_set_payload(const ::std::string& value); - ::std::string* PROTOBUF_NONNULL _internal_mutable_payload(); - - public: - // int32 method = 1; - bool has_method() const; - void clear_method() ; - ::int32_t method() const; - void set_method(::int32_t value); - - private: - ::int32_t _internal_method() const; - void _internal_set_method(::int32_t value); - - public: - // @@protoc_insertion_point(class_scope:transferprotocol.SerializedPacket) - private: - class _Internal; - friend class ::google::protobuf::internal::TcParser; - static const ::google::protobuf::internal::TcParseTable<1, 2, - 0, 49, - 2> - _table_; - - friend class ::google::protobuf::MessageLite; - friend class ::google::protobuf::Arena; - template - friend class ::google::protobuf::Arena::InternalHelper; - using InternalArenaConstructable_ = void; - using DestructorSkippable_ = void; - struct Impl_ { - inline explicit constexpr Impl_(::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_( - ::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - inline explicit Impl_( - ::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Impl_& from, - const SerializedPacket& from_msg); - ::google::protobuf::internal::HasBits<1> _has_bits_; - ::google::protobuf::internal::CachedSize _cached_size_; - ::google::protobuf::internal::ArenaStringPtr payload_; - ::int32_t method_; - PROTOBUF_TSAN_DECLARE_MEMBER - }; - union { Impl_ _impl_; }; - friend struct ::TableStruct_lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto; -}; - -extern const ::google::protobuf::internal::ClassDataFull SerializedPacket_class_data_; - -// =================================================================== - - - - -// =================================================================== - - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // __GNUC__ -// ------------------------------------------------------------------- - -// SerializedPacket - -// int32 method = 1; -inline bool SerializedPacket::has_method() const { - bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; - return value; -} -inline void SerializedPacket::clear_method() { - ::google::protobuf::internal::TSanWrite(&_impl_); - _impl_.method_ = 0; - _impl_._has_bits_[0] &= ~0x00000002u; -} -inline ::int32_t SerializedPacket::method() const { - // @@protoc_insertion_point(field_get:transferprotocol.SerializedPacket.method) - return _internal_method(); -} -inline void SerializedPacket::set_method(::int32_t value) { - _internal_set_method(value); - _impl_._has_bits_[0] |= 0x00000002u; - // @@protoc_insertion_point(field_set:transferprotocol.SerializedPacket.method) -} -inline ::int32_t SerializedPacket::_internal_method() const { - ::google::protobuf::internal::TSanRead(&_impl_); - return _impl_.method_; -} -inline void SerializedPacket::_internal_set_method(::int32_t value) { - ::google::protobuf::internal::TSanWrite(&_impl_); - _impl_.method_ = value; -} - -// string payload = 2; -inline bool SerializedPacket::has_payload() const { - bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0; - return value; -} -inline void SerializedPacket::clear_payload() { - ::google::protobuf::internal::TSanWrite(&_impl_); - _impl_.payload_.ClearToEmpty(); - _impl_._has_bits_[0] &= ~0x00000001u; -} -inline const ::std::string& SerializedPacket::payload() const - ABSL_ATTRIBUTE_LIFETIME_BOUND { - // @@protoc_insertion_point(field_get:transferprotocol.SerializedPacket.payload) - return _internal_payload(); -} -template -PROTOBUF_ALWAYS_INLINE void SerializedPacket::set_payload(Arg_&& arg, Args_... args) { - ::google::protobuf::internal::TSanWrite(&_impl_); - _impl_._has_bits_[0] |= 0x00000001u; - _impl_.payload_.Set(static_cast(arg), args..., GetArena()); - // @@protoc_insertion_point(field_set:transferprotocol.SerializedPacket.payload) -} -inline ::std::string* PROTOBUF_NONNULL SerializedPacket::mutable_payload() - ABSL_ATTRIBUTE_LIFETIME_BOUND { - ::std::string* _s = _internal_mutable_payload(); - // @@protoc_insertion_point(field_mutable:transferprotocol.SerializedPacket.payload) - return _s; -} -inline const ::std::string& SerializedPacket::_internal_payload() const { - ::google::protobuf::internal::TSanRead(&_impl_); - return _impl_.payload_.Get(); -} -inline void SerializedPacket::_internal_set_payload(const ::std::string& value) { - ::google::protobuf::internal::TSanWrite(&_impl_); - _impl_._has_bits_[0] |= 0x00000001u; - _impl_.payload_.Set(value, GetArena()); -} -inline ::std::string* PROTOBUF_NONNULL SerializedPacket::_internal_mutable_payload() { - ::google::protobuf::internal::TSanWrite(&_impl_); - _impl_._has_bits_[0] |= 0x00000001u; - return _impl_.payload_.Mutable( GetArena()); -} -inline ::std::string* PROTOBUF_NULLABLE SerializedPacket::release_payload() { - ::google::protobuf::internal::TSanWrite(&_impl_); - // @@protoc_insertion_point(field_release:transferprotocol.SerializedPacket.payload) - if ((_impl_._has_bits_[0] & 0x00000001u) == 0) { - return nullptr; - } - _impl_._has_bits_[0] &= ~0x00000001u; - auto* released = _impl_.payload_.Release(); - if (::google::protobuf::internal::DebugHardenForceCopyDefaultString()) { - _impl_.payload_.Set("", GetArena()); - } - return released; -} -inline void SerializedPacket::set_allocated_payload(::std::string* PROTOBUF_NULLABLE value) { - ::google::protobuf::internal::TSanWrite(&_impl_); - if (value != nullptr) { - _impl_._has_bits_[0] |= 0x00000001u; - } else { - _impl_._has_bits_[0] &= ~0x00000001u; - } - _impl_.payload_.SetAllocated(value, GetArena()); - if (::google::protobuf::internal::DebugHardenForceCopyDefaultString() && _impl_.payload_.IsDefault()) { - _impl_.payload_.Set("", GetArena()); - } - // @@protoc_insertion_point(field_set_allocated:transferprotocol.SerializedPacket.payload) -} - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif // __GNUC__ - -// @@protoc_insertion_point(namespace_scope) -} // namespace transferprotocol - - -// @@protoc_insertion_point(global_scope) - -#include "google/protobuf/port_undef.inc" - -#endif // lib_2flibtabnet_2fsrc_2fprotobuf_2ftransfer_5fprotocol_2eproto_2epb_2eh diff --git a/lib/libtabnet/src/protobuf/transfer_protocol.proto b/lib/libtabnet/src/protobuf/transfer_protocol.proto deleted file mode 100644 index cfd80f4..0000000 --- a/lib/libtabnet/src/protobuf/transfer_protocol.proto +++ /dev/null @@ -1,8 +0,0 @@ -edition = "2023"; - -package transferprotocol; - -message SerializedPacket { - int32 method = 1; - string payload = 2; -} diff --git a/lib/libtabnet/src/tabnet.cpp b/lib/libtabnet/src/tabnet.cpp index 16143a1..6c133e1 100644 --- a/lib/libtabnet/src/tabnet.cpp +++ b/lib/libtabnet/src/tabnet.cpp @@ -1,211 +1,3 @@ #include "../include/tabnet.h" -#include "tabcrypt.h" -#include "methods.h" -#include "protobuf/transfer_protocol.pb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -std::string secret = ""; - -namespace tabnet { - std::string getLocalIpAddress(std::string interface) { - struct ifaddrs *ifaddr = nullptr; - - // Get linked list of network interfaces - if (getifaddrs(&ifaddr) == -1) { - return ""; - } - - std::string result; - - // Iterate through interfaces - for (auto *ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) continue; - - if (ifa->ifa_addr->sa_family == AF_INET) { - auto *addr = reinterpret_cast(ifa->ifa_addr); - char ip[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &addr->sin_addr, ip, sizeof(ip)); - - // Docker containers typically use eth0 - if (std::string(ifa->ifa_name) == interface) { - result = ip; - break; - } - } - } - - freeifaddrs(ifaddr); - return result; - } - - std::string getBroadcastIpAddress() { - struct ifaddrs* ifaddr = nullptr; - std::string broadcastIP; - - // Get network interfaces - if (getifaddrs(&ifaddr) == -1) { - return ""; - } - - for (struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == nullptr) continue; - - // Only consider IPv4 interfaces that are up and support broadcast - if (ifa->ifa_addr->sa_family == AF_INET && - (ifa->ifa_flags & IFF_BROADCAST) && - (ifa->ifa_flags & IFF_UP) && - !(ifa->ifa_flags & IFF_LOOPBACK)) { - - // Ensure the broadcast address exists - if (ifa->ifa_broadaddr) { - struct sockaddr_in* bcast = - reinterpret_cast(ifa->ifa_broadaddr); - char ip[INET_ADDRSTRLEN]; - if (inet_ntop(AF_INET, &(bcast->sin_addr), ip, INET_ADDRSTRLEN)) { - broadcastIP = ip; - break; // stop at the first valid one - } - } - } - } - - freeifaddrs(ifaddr); - return broadcastIP; - } - - int sendPacket(int socket, tabnet::Packet packet) { - return sendMessage(socket, packet.method, packet.payload); - } - - int sendMessage(int socket, int method, std::string payload) { - transferprotocol::SerializedPacket serializedData; - serializedData.set_method(method); - serializedData.set_payload(payload); - - size_t size = serializedData.ByteSizeLong(); - void *buffer = malloc(size); - serializedData.SerializeToArray(buffer, size); - - //std::string encryptedMessage = tabcrypt::encrypt(secret, data); - std::string stringSize = std::to_string(size); - - // Size has to be 8! - ssize_t s = send(socket, stringSize.c_str(), 8, MSG_NOSIGNAL); - ssize_t n = send(socket, buffer, size, MSG_NOSIGNAL); - if (n < 0) { - if (errno == EPIPE || errno == ECONNRESET) { - return -1; - } - } - return 0; - } - - int sendMessageTo(int socket, const sockaddr_in& broadcast, int method, std::string payload) { - transferprotocol::SerializedPacket serializedData; - serializedData.set_method(method); - serializedData.set_payload(payload); - - size_t size = serializedData.ByteSizeLong(); - void *buffer = malloc(size); - serializedData.SerializeToArray(buffer, size); - - std::string stringSize = std::to_string(size); - - if (sendto(socket, stringSize.c_str(), 8, 0, (struct sockaddr*)&broadcast, sizeof(broadcast)) < 0) { - std::wcout << "size: Sendto Failed!" << std::endl; - return -1; - } - - if (sendto(socket, buffer, size, 0, (struct sockaddr*)&broadcast, sizeof(broadcast)) < 0) { - std::wcout << "buffer: Sendto Failed!" << std::endl; - return -1; - } - - return 0; - } - - Packet receiveMessage(int socket) { - std::string dataString; - transferprotocol::SerializedPacket SerializedData; - Packet data; - - pollfd pfd{}; - pfd.fd = socket; - pfd.events = POLLIN; - - int ret = poll(&pfd, 1, 10000); - - int bufferSize = 1024; - if (ret > 0 && (pfd.revents & POLLIN)) { - char bufferSizeChar[8] = { 0 }; - ssize_t tempSize = recv(socket, bufferSizeChar, sizeof(bufferSizeChar), 0); - if (isNumeric(bufferSizeChar)) { - bufferSize = std::stoi(bufferSizeChar); - } else { - std::wcout << "ReceiveMessage: Error: Bytes are not numeric!" << std::endl; - } - } - - if (ret > 0 && (pfd.revents & POLLIN)) { - char* buffer = new char[bufferSize]; - ssize_t size = recv(socket, buffer, bufferSize, 0); - SerializedData.ParseFromArray(buffer, size); - - data = {SerializedData.method(), SerializedData.payload()}; - - if (size <= 0) return data; - return data; - } - return data; - } - - bool isValidIpV4(std::string &ipString){ - if (ipString.size() < 7) return false; - - int count = 0; - // Seperate Ip Octets - std::stringstream stringStream(ipString); - while (stringStream.good()){ - std::string octet; - getline(stringStream, octet, '.'); - - if (octet.size() > 1){ - if (octet[0] == '0') - return false; - } - - for (int index = 0; index < octet.size(); index++){ - if (isalpha(octet[index])) - return false; - } - - if (stoi(octet) > 255) - return false; - - count++; - } - - if (count != 4) return false; - - return true; - } - - bool isNumeric(const std::string& string) { - static const std::regex numberRegex( - R"(^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$)" - ); - return std::regex_match(string, numberRegex); - } -} +namespace tabnet {}