diff --git a/CMakeLists.txt b/CMakeLists.txt index 2454812..c216bed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,25 +9,11 @@ elseif(UNIX) set(srcs ${srcs} "src/linux_socket.cpp" "src/linux_platform.cpp") endif(WIN32) -option(PTOP_PRINT_DEBUG "Print extra debugging information to the standard output" OFF) -option(PTOP_SPOOF_IP "Insert fake ip addresses into the terminal instead of actual ones" OFF) - -if(PTOP_PRINT_DEBUG) - add_compile_definitions(DATA_COUT=1) -endif() - -if(PTOP_SPOOF_IP) - add_compile_definitions(PTOP_SPOOF_IP=1 PTOP_SPOOF_SERVER="111.111.111.111" PTOP_SPOOF_PUBLIC="123.456.789.101" PTOP_SPOOF_PRIVATE="10.0.0.1" PTOP_SPOOF_ME="1.0.0.1") -else() - add_compile_definitions(PTOP_SPOOF_SERVER="" PTOP_SPOOF_PUBLIC="" PTOP_SPOOF_PRIVATE="") -endif() - set(CMAKE_CXX_STANDARD 17) set(CMAKE_BUILD_TYPE Debug) add_executable(ptop ${PROJECT_SOURCE_DIR}/src/clientmain.cpp ${srcs}) add_executable(ptop_rendezvous ${PROJECT_SOURCE_DIR}/src/servermain.cpp ${srcs}) - if(UNIX) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) diff --git a/CMakePresets.json b/CMakePresets.json deleted file mode 100644 index a06aafc..0000000 --- a/CMakePresets.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "version": 2, - "configurePresets": [ - { - "name": "linux-default", - "displayName": "Linux Debug", - "description": "Target the Windows Subsystem for Linux (WSL) or a remote Linux system.", - "generator": "Ninja", - "binaryDir": "${sourceDir}/out/build/${presetName}", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" - }, - "vendor": { - "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Linux" ] }, - "microsoft.com/VisualStudioRemoteSettings/CMake/1.0": { "sourceDir": "$env{HOME}/.vs/$ms{projectDirName}" } - } - }, - { - "name": "windows-default", - "displayName": "Windows x64 Debug", - "description": "Target Windows with the Visual Studio development environment.", - "generator": "Ninja", - "binaryDir": "${sourceDir}/out/build/${presetName}", - "architecture": { - "value": "x64", - "strategy": "external" - }, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" - }, - "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } - }, - { - "name": "Windows Spoof", - "displayName": "Windows x64 Debug", - "description": "Target Windows with the Visual Studio development environment.", - "generator": "Ninja", - "binaryDir": "${sourceDir}/out/build/${presetName}", - "architecture": { - "value": "x64", - "strategy": "external" - }, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}", - "PTOP_SPOOF_IP": "ON" - }, - "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } - } - ] -} \ No newline at end of file diff --git a/src/client.cpp b/src/client.cpp index dc0680f..41b4f95 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -30,26 +30,23 @@ std::unique_ptr& client_init_kit::get_server_socket() { void client_init_kit::set_server_socket(std::unique_ptr&& input) { _server_socket = std::move(input); + + if(input == nullptr) + std::cout << "client_init_kit: connection socket set to nullptr mmk?" << std::endl; } client_peer_kit::client_peer_kit() { - + } void client_peer_kit::set_peer_data(client_init_kit& init_kit, const char* data, int next_data_index, MESSAGE_LENGTH_T data_len) { public_info = read_peer_data(data, next_data_index, data_len); private_info = read_peer_data(data, next_data_index, data_len); -#ifdef PTOP_SPOOF_IP - std::cout << "Target is: " << PTOP_SPOOF_PRIVATE << ":" << private_info.port << "/" << PTOP_SPOOF_PUBLIC << ":" << public_info.port << " priv/pub" << std::endl; -#else std::cout << "Target is: " << private_info.ip_address << ":" << private_info.port << "/" << public_info.ip_address << ":" << public_info.port << " priv/pub" << std::endl; -#endif old_privatename = init_kit.get_server_socket()->get_myname_raw(); - std::cout << "Closing socket to server" << std::endl; init_kit.set_server_socket(nullptr); //need to close the server socket HERE to maintain the same session in the peer sockets - std::cout << "Creating the listen socket..." << std::endl; if (init_kit.protocol.is_udp()) listen_sock = std::make_unique(old_privatename, init_kit.protocol, "HolePunch-Listen"); else @@ -57,9 +54,8 @@ void client_peer_kit::set_peer_data(client_init_kit& init_kit, const char* data, listen_sock->listen(); - std::cout << "Creating Connectors to the public and private targets..." << std::endl; - public_connector = std::make_unique(old_privatename, public_info.ip_address, public_info.port, init_kit.protocol, "HolePunch-Public", PTOP_SPOOF_PUBLIC); - private_connector = std::make_unique(old_privatename, private_info.ip_address, private_info.port, init_kit.protocol, "HolePunch-Private", PTOP_SPOOF_PRIVATE); + public_connector = std::make_unique(old_privatename, public_info.ip_address, public_info.port, init_kit.protocol, "HolePunch-Public"); + private_connector = std::make_unique(old_privatename, private_info.ip_address, private_info.port, init_kit.protocol, "HolePunch-Private"); peer_connect_start_time = std::chrono::system_clock::now(); @@ -79,7 +75,7 @@ EXECUTION_STATUS connect_public(client_init_kit& init_kit, client_peer_kit& peer { std::cout << "Public Connection Failed, Retrying connection..." << std::endl; peer_kit.public_connector = nullptr; - peer_kit.public_connector = std::make_unique(peer_kit.old_privatename, peer_kit.public_info.ip_address, peer_kit.public_info.port, init_kit.protocol, "HolePunch-Public", PTOP_SPOOF_PUBLIC); + peer_kit.public_connector = std::make_unique(peer_kit.old_privatename, peer_kit.public_info.ip_address, peer_kit.public_info.port, init_kit.protocol, "HolePunch-Public"); } return EXECUTION_STATUS::HOLE_PUNCH; } @@ -98,7 +94,7 @@ EXECUTION_STATUS connect_private(client_init_kit& init_kit, client_peer_kit& pee { std::cout << "Private Connection attempt failed, retrying..." << std::endl; peer_kit.private_connector = nullptr; - peer_kit.private_connector = std::make_unique(peer_kit.old_privatename, peer_kit.private_info.ip_address, peer_kit.private_info.port, init_kit.protocol, "HolePunch-Private", PTOP_SPOOF_PRIVATE); + peer_kit.private_connector = std::make_unique(peer_kit.old_privatename, peer_kit.private_info.ip_address, peer_kit.private_info.port, init_kit.protocol, "HolePunch-Private"); } return EXECUTION_STATUS::HOLE_PUNCH; } @@ -144,12 +140,6 @@ EXECUTION_STATUS hole_punch(client_init_kit& init_kit, client_peer_kit& peer_kit return EXECUTION_STATUS::FAILED; } - if (status == EXECUTION_STATUS::PEER_CONNECTED) - { - std::cout << "We have hole punched to the peer!" << std::endl; - std::cout << "Try sending a message with 'msg: [text]' or a file with 'file: [filename]'" << std::endl; - } - return status; } catch (const std::exception& e) @@ -178,7 +168,6 @@ EXECUTION_STATUS process_server_data(client_init_kit& init_kit, client_peer_kit& { case MESSAGE_TYPE::CONNECT_TO_PEER: { - std::cout << "Rendezvous server has responded, we are now attempting to hole punch..." << std::endl; if (init_kit.do_delay) { std::cout << "Delaying hole punching by 5s..." << std::endl; @@ -289,9 +278,7 @@ EXECUTION_STATUS process_peer_data(const Message& mess, const std::unique_ptr take_message_lock(message_queue.queue_mutex, std::defer_lock); init_kit.status = EXECUTION_STATUS::RENDEZVOUS; - std::cout << "Connected to rendezvous server, now awaiting another peer..." << std::endl; while (init_kit.status != EXECUTION_STATUS::COMPLETE && init_kit.status != EXECUTION_STATUS::FAILED) //listen at the start of protocol { diff --git a/src/clientmain.cpp b/src/clientmain.cpp index 53681e1..629b157 100644 --- a/src/clientmain.cpp +++ b/src/clientmain.cpp @@ -37,36 +37,26 @@ using namespace std::chrono; -int clientmain() -{ +int main(int argc, char** argv) { + try + { #if defined(WIN32) | defined(_WIN64) // windows_internet uses RAII to ensure WSAStartup and WSACleanup get called in the proper order - windows_internet wsa_wrapper(MAKEWORD(2, 2)); + windows_internet wsa_wrapper(MAKEWORD(2, 2)); #endif - std::cout << "Please enter the rendezvous server's IP:" << std::endl; - std::string raw_ip{}; + std::cout << "Please enter the rendezvous server's IP:" << std::endl; + std::string raw_ip{}; - std::cin >> raw_ip; - std::getline(std::cin, std::string()); // Discard the newline that confuses the next input + std::cin >> raw_ip; - if (raw_ip == "") { - std::this_thread::sleep_for(100ms); //epic optimization - return 0; - } - Protocol validated{ "udp" }; - - client_loop(raw_ip, validated); -} + if (raw_ip == "") { + std::this_thread::sleep_for(100ms); //epic optimization + return 0; + } + Protocol validated{ "udp" }; -int main(int argc, char** argv) { - - if (argc > 1 && !strcmp(argv[1], "no-catch")) - return clientmain(); - - try - { - clientmain(); + client_loop(raw_ip, validated); } catch (const std::exception& e) { diff --git a/src/linux_platform.cpp b/src/linux_platform.cpp index e839e84..b71f763 100644 --- a/src/linux_platform.cpp +++ b/src/linux_platform.cpp @@ -133,6 +133,16 @@ readable_ip_info Platform::get_peer_data() const return out; } +raw_name_data Platform::get_peername_raw() const +{ + return _socket.get_peer_raw(); +} + +raw_name_data Platform::get_myname_raw() const +{ + return _socket.get_name_raw(); +} + PtopSocket listen_construct(std::string port, Protocol input_proto, std::string name) { std::cout << "[Listen] Creating new Socket on port (with localhost, named: " << name << "): " << port << std::endl; @@ -344,4 +354,66 @@ std::unique_ptr NonBlockingListener::accept_connection() return std::make_unique(std::move(new_sock)); } +PtopSocket reuse_connection_construct(raw_name_data data, Protocol proto, std::string name) +{ + auto readable = convert_to_readable(data); + std::cout << "[DataReuseNoB] Creating Connection socket '" << name << "' bound to : " << readable.ip_address << ":" << readable.port << std::endl; + auto conn_socket = PtopSocket(proto, name); + + if (conn_socket.is_invalid()) + throw_new_exception("[DataReuseNoB] Failed to create nonblocking socket: " + linux_error(), LINE_CONTEXT); + + conn_socket.set_non_blocking(true); + conn_socket.set_socket_reuse(); + + conn_socket.bind_socket(data, std::string("[DataReuseNoB] (") + name + ") Failed to bind"); + std::cout << "[DataReuseNoB] Successfully bound Data socket (" << name << ") to: " << readable.ip_address << ":" << readable.port << std::endl; + + return conn_socket; +} + +NonBlockingConnector::NonBlockingConnector(raw_name_data data, std::string ip_address, std::string port, Protocol proto, std::string name) +: Platform(reuse_connection_construct(data, proto, name)) +{ + // if tcp? + try + { + this->connect(ip_address, port); + } + catch (const std::exception& e) + { + throw_with_context(e, LINE_CONTEXT); + } +} + +void NonBlockingConnector::connect(std::string ip_address, std::string port) +{ + try + { + std::cout << "[DataReuseNoB] (" << get_name() << ") Trying to connect to : " << ip_address << ":" << port << std::endl; + struct addrinfo* results, hints; + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + int iResult = 0; + + iResult = getaddrinfo(ip_address.c_str(), port.c_str(), &hints, &results); + if (iResult != 0) + throw_new_exception("Socket '" + get_name() + "' Failed to getaddrinfo, error: " + std::to_string(iResult), LINE_CONTEXT); + + if (results == nullptr) + throw_new_exception(("No possible sockets found for '") + ip_address + ":" + port + "' (socket '" + get_name() + "')", LINE_CONTEXT); + + _socket.connect(results->ai_addr, results->ai_addrlen); + std::cout << "[DataReuseNoB] (" << get_name() << ") Successfully BEGUN Connection to : " << ip_address << ":" << port << std::endl; + try_update_endpoint_info(); + } + catch (const std::exception& e) + { + throw_with_context(e, LINE_CONTEXT); + } +} + #endif \ No newline at end of file diff --git a/src/linux_socket.cpp b/src/linux_socket.cpp index 65dd6d4..b029df5 100644 --- a/src/linux_socket.cpp +++ b/src/linux_socket.cpp @@ -53,10 +53,8 @@ PtopSocket::~PtopSocket() if (is_valid()) { - auto lock = std::unique_lock(*_handle_mutex); -#ifdef DATA_COUT + auto lock = std::unique_lock(*_handle_mutex); std::cout << "Closing socket" << std::endl; -#endif close(*_handle); *_handle = REALLY_INVALID_SOCKET; _handle = nullptr; diff --git a/src/platform.cpp b/src/platform.cpp index b148eb7..ec62b7a 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -10,9 +10,6 @@ #include #include #include -#define zmem bzero -#else -#define zmem ZeroMemory #endif #include @@ -56,46 +53,9 @@ readable_ip_info convert_to_readable(const raw_name_data& data) return out; } -raw_name_data convert_to_raw(const readable_ip_info& data) -{ - struct addrinfo* result = NULL, - * ptr = NULL, - hints; - -#ifdef WIN32 - ZeroMemory(&hints, sizeof(hints)); -#elif defined(__linux__) - bzero(&hints, sizeof(hints)); -#endif - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - - int n = getaddrinfo(data.ip_address.c_str(), data.port.c_str(), &hints, &result); - - if (n == SOCKET_ERROR || result == 0) - return raw_name_data{}; - - return raw_name_data{ *result->ai_addr, (socklen_t)result->ai_addrlen }; -} - -raw_name_data Platform::get_peername_raw() const -{ - return _socket.get_peer_raw(); -} - -raw_name_data Platform::get_myname_raw() const -{ - return _socket.get_name_raw(); -} - PtopSocket data_connect_construct(std::string peer_address, std::string peer_port, Protocol ip_proto, std::string name) { -#ifdef PTOP_SPOOF_IP - std::cout << "[Data] Creating a Data Socket (named " << name << ")..." << std::endl; -#else std::cout << "[Data] Creating a Data Socket (named " << name << ") connecting to : " << peer_address << ":" << peer_port << std::endl; -#endif struct addrinfo* result = NULL, * ptr = NULL, @@ -114,14 +74,8 @@ PtopSocket data_connect_construct(std::string peer_address, std::string peer_por if (n == SOCKET_ERROR) throw_new_exception("Failed to get address info for: (" + name + ") " + peer_address + ":" + peer_port + " with: " + get_last_error(), LINE_CONTEXT); - if (result == 0) - throw_new_exception("Invalid IP Address supplied: " + name, LINE_CONTEXT); -#ifdef PTOP_SPOOF_IP - auto conn_socket = PtopSocket(ip_proto, convert_to_raw(readable_ip_info{ std::string(PTOP_SPOOF_SERVER), ServerListenPort }), name); -#else auto conn_socket = PtopSocket(ip_proto, name); -#endif conn_socket.set_socket_reuse(); conn_socket.connect(result->ai_addr, result->ai_addrlen); @@ -151,80 +105,10 @@ PlatformAnalyser::PlatformAnalyser(std::string peer_address, std::string peer_po Platform::~Platform() { -#ifdef DATA_COUT if (_socket.is_valid()) std::cout << "Closing socket: " << get_identifier_str() << std::endl; else std::cout << "Closing Dead socket" << std::endl; -#endif -} - - -PtopSocket reuse_connection_construct(raw_name_data data, Protocol proto, std::string name, std::string spoof_ip) -{ - auto readable = convert_to_readable(data); -#ifdef PTOP_SPOOF_IP - auto conn_socket = PtopSocket(proto, convert_to_raw(readable_ip_info{ spoof_ip, convert_to_readable(data).port }), name); -#else - auto conn_socket = PtopSocket(proto, name); -#endif - - if (conn_socket.is_invalid()) - throw_new_exception("[DataReuseNoB] Failed to create nonblocking socket: " + get_last_error(), LINE_CONTEXT); - - conn_socket.set_non_blocking(true); - conn_socket.set_socket_reuse(); - - conn_socket.bind_socket(data, std::string("[DataReuseNoB] (") + name + ") Failed to bind"); -#ifdef PTOP_SPOOF_IP - std::cout << "[DataReuseNoB] Successfully created Data socket (" << name << ") bound to: " << readable.ip_address << ":" << readable.port << std::endl; -#else - std::cout << "[DataReuseNoB] Successfully created Data socket (" << name << ") bound to: " << readable.ip_address << ":" << readable.port << std::endl; -#endif - - return conn_socket; -} - -NonBlockingConnector::NonBlockingConnector( - raw_name_data data, std::string ip_address, std::string port, Protocol input_protocol, std::string name, std::string spoof_ip) - : Platform( - reuse_connection_construct(data, input_protocol, name, spoof_ip) - ) -{ - connect(ip_address, port); -} - -void NonBlockingConnector::connect(std::string ip_address, std::string port) -{ - try - { - struct addrinfo* results, hints; - zmem(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - int iResult = 0; - - iResult = getaddrinfo(ip_address.c_str(), port.c_str(), &hints, &results); - if (iResult != 0) - throw_new_exception("Socket '" + get_name() + "' Failed to getaddrinfo, error: " + std::to_string(iResult), LINE_CONTEXT); - - if (results == nullptr) - throw_new_exception(("No possible sockets found for '") + ip_address + ":" + port + "' (socket '" + get_name() + "')", LINE_CONTEXT); - - _socket.connect(results->ai_addr, results->ai_addrlen); -#ifdef PTOP_SPOOF_IP - std::cout << "[DataReuseNoB] (" << get_name() << ") Initiated Connection" << std::endl; -#else - std::cout << "[DataReuseNoB] (" << get_name() << ") Initiated Connection to : " << ip_address << ":" << port << std::endl; -#endif - try_update_endpoint_info(); - } - catch (const std::exception& e) - { - throw_with_context(e, LINE_CONTEXT); - } } bool do_udp_handshake(UDPHandShakeStatus& handshake_status, PtopSocket& socket) @@ -610,13 +494,16 @@ PtopSocket construct_udp_listener(std::string port, Protocol proto, std::string if (!proto.is_udp()) throw_new_exception("UDP Listener must only be used with UDP", LINE_CONTEXT); - auto listen_socket = PtopSocket(proto, raw_name_data{}, name); + auto listen_socket = PtopSocket(proto, name); struct sockaddr_in serv_addr; int portno = atoi(port.c_str()); - zmem(&serv_addr, sizeof(serv_addr)); - +#ifdef WIN32 + ZeroMemory(&serv_addr, sizeof(serv_addr)); +#elif __linux__ + bzero((char*)&serv_addr, sizeof(serv_addr)); +#endif serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); @@ -629,13 +516,12 @@ PtopSocket construct_udp_listener(std::string port, Protocol proto, std::string PtopSocket construct_udp_nonblocking_listener(raw_name_data bind_name, Protocol proto, std::string name) { - auto listen_socket = PtopSocket(proto, convert_to_raw(readable_ip_info{ "0.0.0.0", "00000" }), name); + auto listen_socket = PtopSocket(proto, name); listen_socket.set_non_blocking(true); listen_socket.set_socket_reuse(); listen_socket.bind_socket(bind_name); - std::cout << "[UDPListen] Created and bound UDP Listener (" << name << ") to port " << convert_to_readable(bind_name).port << " (the port we just had with the rendezvous server)" << std::endl; return listen_socket; } diff --git a/src/platform.h b/src/platform.h index 7bc2200..e7ccb70 100644 --- a/src/platform.h +++ b/src/platform.h @@ -17,7 +17,6 @@ using namespace std::chrono_literals; readable_ip_info convert_to_readable(const raw_name_data&); -raw_name_data convert_to_raw(const readable_ip_info& info); struct UDPHandShakeStatus { @@ -113,8 +112,8 @@ class NonBlockingListener : public Platform, public virtual INonBlockingListener class NonBlockingConnector : public Platform, public virtual INonBlockingConnector { UDPHandShakeStatus _handshake_status; -public: - NonBlockingConnector(raw_name_data private_binding, std::string ip_address, std::string port, Protocol input_protocol, std::string name, std::string spoof_ip); + public: + NonBlockingConnector(raw_name_data private_binding, std::string ip_address, std::string port, Protocol input_protocol, std::string); void connect(std::string ip_address, std::string port) override; // Called in constructor, can be called again if it fails ConnectionStatus has_connected() override; diff --git a/src/ptop_socket.cpp b/src/ptop_socket.cpp index 5cfdbd2..8458ed9 100644 --- a/src/ptop_socket.cpp +++ b/src/ptop_socket.cpp @@ -79,8 +79,7 @@ void poll_thread_func(std::shared_ptr handle, std::shared_ptr(handle)) - , _protocol(proto) + : _handle(std::make_shared(handle)), _protocol(proto) , _handle_mutex(std::make_shared()) , _name(name) , _message_obj_mutex(std::make_shared()) @@ -89,15 +88,8 @@ PtopSocket::PtopSocket(SOCKET handle, Protocol proto, std::string name) _polling_thread = std::thread(poll_thread_func, _handle, _handle_mutex, _shared_message_obj, _message_obj_mutex, _protocol, _thread_die); } -#ifdef PTOP_SPOOF_IP -PtopSocket::PtopSocket(SOCKET handle, Protocol proto, raw_name_data endpoint, raw_name_data spoofpoint, std::string name) -#else PtopSocket::PtopSocket(SOCKET handle, Protocol proto, raw_name_data endpoint, std::string name) -#endif : _handle(std::make_shared(handle)) -#ifdef PTOP_SPOOF_IP - , _spoofpoint(spoofpoint) -#endif , _handle_mutex(std::make_shared()) , _protocol(proto) , _endpoint(endpoint) @@ -108,15 +100,8 @@ PtopSocket::PtopSocket(SOCKET handle, Protocol proto, raw_name_data endpoint, st _polling_thread = std::thread(poll_thread_func, _handle, _handle_mutex, _shared_message_obj, _message_obj_mutex, _protocol, _thread_die); } -#ifdef PTOP_SPOOF_IP -PtopSocket::PtopSocket(Protocol proto, raw_name_data spoofpoint, std::string name) -#else PtopSocket::PtopSocket(Protocol proto, std::string name) -#endif : _protocol(proto) -#ifdef PTOP_SPOOF_IP - , _spoofpoint(spoofpoint) -#endif , _handle_mutex(std::make_shared()) , _name(std::move(name)) , _message_obj_mutex(std::make_shared()) @@ -190,7 +175,7 @@ PtopSocket PtopSocket::accept_data_socket() { throw_new_exception("Failed to accept incoming connection: " + get_last_error(), LINE_CONTEXT); } - auto new_sock = PtopSocket(new_socket, _protocol, raw_name_data(client_addr), raw_name_data{}, "Accepted Data Socket"); + auto new_sock = PtopSocket(new_socket, _protocol, raw_name_data(client_addr)); new_sock.set_socket_option(SO_KEEPALIVE, (int)1); return new_sock; } @@ -309,9 +294,6 @@ bool PtopSocket::has_died() raw_name_data PtopSocket::get_peer_raw() const { -#ifdef PTOP_SPOOF_IP - return _spoofpoint; -#else sockaddr_in peer_name; socklen_t peer_size = sizeof(peer_name); int n = getpeername(*_handle, (sockaddr*)&peer_name, &peer_size); @@ -321,7 +303,6 @@ raw_name_data PtopSocket::get_peer_raw() const raw_data.name = *(sockaddr*)&peer_name; raw_data.name_len = peer_size; return raw_data; -#endif } raw_name_data PtopSocket::get_name_raw() const @@ -362,4 +343,4 @@ udp_bytes PtopSocket::receive_udp_bytes(){ _shared_message_obj->erase(_shared_message_obj->begin()); return first_msg; -} +} \ No newline at end of file diff --git a/src/ptop_socket.h b/src/ptop_socket.h index 92b3391..78cf57c 100644 --- a/src/ptop_socket.h +++ b/src/ptop_socket.h @@ -41,9 +41,6 @@ class PtopSocket std::shared_ptr _handle; Protocol _protocol; raw_name_data _endpoint; -#ifdef PTOP_SPOOF_IP - raw_name_data _spoofpoint; -#endif std::string _name; std::thread _polling_thread; std::shared_ptr _handle_mutex; @@ -53,19 +50,11 @@ class PtopSocket std::shared_ptr _thread_die = std::make_shared(false); PtopSocket(SOCKET handle, Protocol proto, std::string name = ""); -#ifdef PTOP_SPOOF_IP - PtopSocket(SOCKET handle, Protocol proto, raw_name_data endpoint, raw_name_data spoofpoint, std::string name = ""); -#else PtopSocket(SOCKET handle, Protocol proto, raw_name_data endpoint, std::string name = ""); -#endif public: -#ifdef PTOP_SPOOF_IP - explicit PtopSocket(Protocol proto, raw_name_data spoofpoint, std::string name = ""); -#else explicit PtopSocket(Protocol proto, std::string name = ""); -#endif PtopSocket(PtopSocket&& other); ~PtopSocket(); diff --git a/src/windows_platform.cpp b/src/windows_platform.cpp index e53fa60..52318ed 100644 --- a/src/windows_platform.cpp +++ b/src/windows_platform.cpp @@ -19,6 +19,7 @@ Platform::Platform(PtopSocket&& socket) // big chungus if(_socket.is_udp()) { + std::cout << "Platform constructed for UDP" << std::endl; return; } @@ -156,6 +157,39 @@ readable_ip_info Platform::get_peer_data() const return out; } +raw_name_data Platform::get_peername_raw() const +{ + sockaddr_in peer_name; + socklen_t peer_size = sizeof(peer_name); + int n = getpeername(_socket.get_handle(), (sockaddr*)&peer_name, &peer_size); + if (n != 0) { + auto error = std::string("[Socket] (" + get_name() + ") Failed to getpeername : ") + get_last_error(); + throw_new_exception(error, LINE_CONTEXT); + } + + raw_name_data raw_data; + raw_data.name = *(sockaddr*)&peer_name; + raw_data.name_len = peer_size; + return raw_data; +} + +raw_name_data Platform::get_myname_raw() const +{ + sockaddr_in peer_name; + socklen_t peer_size = sizeof(peer_name); + int n = getsockname(_socket.get_handle(), (sockaddr*)&peer_name, &peer_size); + + if (n != 0) { + auto error = std::string("[Socket] (" + get_name() + ") Failed to getsockname : ") + get_last_error(); + throw_new_exception(error, LINE_CONTEXT); + } + + raw_name_data raw_data; + raw_data.name = *(sockaddr*)&peer_name; + raw_data.name_len = peer_size; + return raw_data; +} + PtopSocket construct_windowslistensocket(std::string port, Protocol input_protocol, std::string name) { try { @@ -175,7 +209,7 @@ PtopSocket construct_windowslistensocket(std::string port, Protocol input_protoc throw std::exception((std::string("[Listen] (" + name + ") Failed to create windows socket : getaddrinfo failed with") + std::to_string(iResult)).c_str()); } - PtopSocket conn_socket = PtopSocket(input_protocol, raw_name_data{}, name); + PtopSocket conn_socket = PtopSocket(input_protocol, name); if (conn_socket.is_invalid()) { @@ -267,9 +301,7 @@ void PlatformAnalyser::process_socket_data() data_read += length; auto new_message = Message{ type, length, std::move(data) }; _stored_messages.push(new_message); -#ifdef DATA_COUT std::cout << "Socket " << Platform::get_identifier_str() << " Received " << "a Message of type: " << mt_to_string(new_message.Type) << " with length: " << new_message.Length << " bytes (+ " << sizeof(type) + sizeof(length) << " type/length bytes)" << std::endl; -#endif } } else @@ -335,7 +367,7 @@ PtopSocket windows_reuse_nb_listen_construct(raw_name_data data, Protocol proto, auto readable = convert_to_readable(data); std::cout << "[ListenReuseNoB] Creating Reusable Listen Socket '" << name << "' on: " << readable.ip_address << ":" << readable.port << std::endl; - PtopSocket listen_socket = PtopSocket(proto, raw_name_data{}, name); + PtopSocket listen_socket = PtopSocket(proto, name); if (listen_socket.is_invalid()) throw_new_exception("[ListenReuseNoB] (" + name + ") " + readable.ip_address + ":" + readable.port + " Failed to create reusable nonblocking listen socket: " + get_last_error(), LINE_CONTEXT); @@ -377,4 +409,66 @@ std::unique_ptr NonBlockingListener::accept_connection() return std::make_unique(std::move(new_sock)); } +PtopSocket windows_reuse_nb_construct(raw_name_data data, Protocol proto, std::string name) +{ + try { + auto readable = convert_to_readable(data); + std::cout << "[DataReuseNoB] Creating Connection socket '" << name << "' bound to : " << readable.ip_address << ":" << readable.port << std::endl; + auto conn_socket = PtopSocket(proto, name); + if (conn_socket.is_invalid()) + throw_new_exception(std::string("[DataReuseNoB] Failed to create nonblocking socket (" + name + "): ") + get_last_error(), LINE_CONTEXT); + + conn_socket.set_non_blocking(true); + conn_socket.set_socket_reuse(); + + conn_socket.bind_socket(data, "[DataReuseNoB] '" + name + "' Failed to bind"); + std::cout << "[DataReuseNoB] Successfully bound Data socket (" << name << ") to: " << readable.ip_address << " : " << readable.port << std::endl; + + return conn_socket; + } + catch (const std::exception& e) + { + throw_with_context(e, LINE_CONTEXT); + } +} + +NonBlockingConnector::NonBlockingConnector( + raw_name_data data, std::string ip_address, std::string port, Protocol input_protocol, std::string name) + : Platform( + windows_reuse_nb_construct(data, input_protocol, name) + ) +{ + connect(ip_address, port); +} + +void NonBlockingConnector::connect(std::string ip_address, std::string port) +{ + try + { + std::cout << "[DataReuseNoB] (" << get_name() << ") Trying to connect to : " << ip_address << ":" << port << std::endl; + struct addrinfo* results, hints; + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + int iResult = 0; + + iResult = getaddrinfo(ip_address.c_str(), port.c_str(), &hints, &results); + if (iResult != 0) + throw_new_exception("Socket '" + get_name() + "' Failed to getaddrinfo, error: " + std::to_string(iResult), LINE_CONTEXT); + + if (results == nullptr) + throw_new_exception(("No possible sockets found for '") + ip_address + ":" + port + "' (socket '" + get_name() + "')", LINE_CONTEXT); + + _socket.connect(results->ai_addr, (socklen_t)results->ai_addrlen); + std::cout << "[DataReuseNoB] (" << get_name() << ") Successfully BEGUN Connection to : " << ip_address << ":" << port << std::endl; + try_update_endpoint_info(); + } + catch (const std::exception& e) + { + throw_with_context(e, LINE_CONTEXT); + } +} + #endif \ No newline at end of file diff --git a/src/windows_socket.cpp b/src/windows_socket.cpp index cd6ca1f..9b62f1d 100644 --- a/src/windows_socket.cpp +++ b/src/windows_socket.cpp @@ -41,9 +41,7 @@ PtopSocket::~PtopSocket() if (is_valid()) { auto lock = std::unique_lock(*_handle_mutex); -#ifdef DATA_COUT std::cout << "Closing socket" << std::endl; -#endif closesocket(*_handle); *_handle = REALLY_INVALID_SOCKET; _handle = nullptr;