From 9897394d944821cdd492e333554343e52609fc6b Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Tue, 1 Oct 2024 15:10:51 +0200 Subject: [PATCH 01/11] change actions --- .github/workflows/debian-dev.yml | 12 ++++++------ .github/workflows/debian.yml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/debian-dev.yml b/.github/workflows/debian-dev.yml index 44a05a8..3e332ce 100644 --- a/.github/workflows/debian-dev.yml +++ b/.github/workflows/debian-dev.yml @@ -29,17 +29,17 @@ jobs: cd .. mkdir -p nipovpn/usr/bin/ cp build/core/nipovpn nipovpn/usr/bin/nipovpn - dpkg-deb --build nipovpn/ build/nipovpn-stage.deb + dpkg-deb --build nipovpn/ build/nipovpn_staging_v1-0-${{ github.run_number }}.deb - name: Upload the Debian nipovpn as an artifact uses: actions/upload-artifact@v3 with: name: nipovpn - path: build/nipovpn-stage.deb + path: build/nipovpn_staging_v1-0-${{ github.run_number }}.deb - name: Show nipovpn information run: | - dpkg -I build/nipovpn-stage.deb + dpkg -I build/nipovpn_staging_v1-0-${{ github.run_number }}.deb release: needs: build @@ -59,7 +59,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: tag_name: 'v1.0.${{ github.run_number }}' - release_name: Release ${{ github.run_number }} + release_name: Staging v1.0.${{ github.run_number }} draft: false prerelease: true @@ -69,6 +69,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./nipovpn-stage.deb - asset_name: nipovpn-stage.deb + asset_path: ./nipovpn_staging_v1-0-${{ github.run_number }}.deb + asset_name: nipovpn_staging_v1-0-${{ github.run_number }}.deb asset_content_type: application/octet-stream diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 011d1b7..2e0ae90 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -29,17 +29,17 @@ jobs: cd .. mkdir -p nipovpn/usr/bin/ cp build/core/nipovpn nipovpn/usr/bin/nipovpn - dpkg-deb --build nipovpn/ build/nipovpn.deb + dpkg-deb --build nipovpn/ build/nipovpn_v1-0-${{ github.run_number }}.deb - name: Upload the Debian nipovpn as an artifact uses: actions/upload-artifact@v3 with: name: nipovpn - path: build/nipovpn.deb + path: build/nipovpn_v1-0-${{ github.run_number }}.deb - name: Show nipovpn information run: | - dpkg -I build/nipovpn.deb + dpkg -I build/nipovpn_v1-0-${{ github.run_number }}.deb release: needs: build @@ -59,7 +59,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: tag_name: 'v1.0.${{ github.run_number }}' - release_name: Release ${{ github.run_number }} + release_name: Version v1.0.${{ github.run_number }} draft: false prerelease: false @@ -69,6 +69,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./nipovpn.deb - asset_name: nipovpn.deb + asset_path: ./nipovpn_v1-0-${{ github.run_number }}.deb + asset_name: nipovpn_v1-0-${{ github.run_number }}.deb asset_content_type: application/octet-stream From 57c64563cad7cfa2c84337b82ab1bd0e9904d26f Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Tue, 1 Oct 2024 15:10:51 +0200 Subject: [PATCH 02/11] change actions --- .github/workflows/debian-dev.yml | 13 +++++++------ .github/workflows/debian.yml | 12 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/debian-dev.yml b/.github/workflows/debian-dev.yml index 44a05a8..6064a97 100644 --- a/.github/workflows/debian-dev.yml +++ b/.github/workflows/debian-dev.yml @@ -6,6 +6,7 @@ on: - dev paths: - 'core/src/**' + - '.github/workflows/**' jobs: build: @@ -29,17 +30,17 @@ jobs: cd .. mkdir -p nipovpn/usr/bin/ cp build/core/nipovpn nipovpn/usr/bin/nipovpn - dpkg-deb --build nipovpn/ build/nipovpn-stage.deb + dpkg-deb --build nipovpn/ build/nipovpn_staging_v1-0-${{ github.run_number }}.deb - name: Upload the Debian nipovpn as an artifact uses: actions/upload-artifact@v3 with: name: nipovpn - path: build/nipovpn-stage.deb + path: build/nipovpn_staging_v1-0-${{ github.run_number }}.deb - name: Show nipovpn information run: | - dpkg -I build/nipovpn-stage.deb + dpkg -I build/nipovpn_staging_v1-0-${{ github.run_number }}.deb release: needs: build @@ -59,7 +60,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: tag_name: 'v1.0.${{ github.run_number }}' - release_name: Release ${{ github.run_number }} + release_name: Staging v1.0.${{ github.run_number }} draft: false prerelease: true @@ -69,6 +70,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./nipovpn-stage.deb - asset_name: nipovpn-stage.deb + asset_path: ./nipovpn_staging_v1-0-${{ github.run_number }}.deb + asset_name: nipovpn_staging_v1-0-${{ github.run_number }}.deb asset_content_type: application/octet-stream diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 011d1b7..2e0ae90 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -29,17 +29,17 @@ jobs: cd .. mkdir -p nipovpn/usr/bin/ cp build/core/nipovpn nipovpn/usr/bin/nipovpn - dpkg-deb --build nipovpn/ build/nipovpn.deb + dpkg-deb --build nipovpn/ build/nipovpn_v1-0-${{ github.run_number }}.deb - name: Upload the Debian nipovpn as an artifact uses: actions/upload-artifact@v3 with: name: nipovpn - path: build/nipovpn.deb + path: build/nipovpn_v1-0-${{ github.run_number }}.deb - name: Show nipovpn information run: | - dpkg -I build/nipovpn.deb + dpkg -I build/nipovpn_v1-0-${{ github.run_number }}.deb release: needs: build @@ -59,7 +59,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: tag_name: 'v1.0.${{ github.run_number }}' - release_name: Release ${{ github.run_number }} + release_name: Version v1.0.${{ github.run_number }} draft: false prerelease: false @@ -69,6 +69,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./nipovpn.deb - asset_name: nipovpn.deb + asset_path: ./nipovpn_v1-0-${{ github.run_number }}.deb + asset_name: nipovpn_v1-0-${{ github.run_number }}.deb asset_content_type: application/octet-stream From 7517c329fd4933e7816fe20960a57490d8031f08 Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Wed, 2 Oct 2024 13:30:20 +0200 Subject: [PATCH 03/11] Implement chunkSize in config --- core/src/config.cpp | 4 +++- core/src/config.hpp | 1 + core/src/general.hpp | 12 ++++++++++++ nipovpn/etc/nipovpn/config.yaml | 5 ++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/core/src/config.cpp b/core/src/config.cpp index 34151d4..2ce7705 100644 --- a/core/src/config.cpp +++ b/core/src/config.cpp @@ -11,7 +11,8 @@ Config::Config(const RunMode &mode, const std::string &filePath) configYaml_["general"]["method"].as<std::string>(), configYaml_["general"]["timeWait"].as<unsigned int>(), configYaml_["general"]["timeout"].as<unsigned short>(), - configYaml_["general"]["repeatWait"].as<unsigned short>()}), + configYaml_["general"]["repeatWait"].as<unsigned short>(), + configYaml_["general"]["chunkSize"].as<unsigned short>()}), log_({configYaml_["log"]["logLevel"].as<std::string>(), configYaml_["log"]["logFile"].as<std::string>()}), server_({configYaml_["server"]["threads"].as<unsigned short>(), @@ -62,6 +63,7 @@ std::string Config::toString() const { << " timeWait: " << general_.timeWait << "\n" << " timeout: " << general_.timeout << "\n" << " repeatWait: " << general_.repeatWait << "\n" + << " chunkSize: " << general_.chunkSize << "\n" << " Log :\n" << " logLevel: " << log_.level << "\n" << " logFile: " << log_.file << "\n" diff --git a/core/src/config.hpp b/core/src/config.hpp index 7266d6a..7d1e8c6 100644 --- a/core/src/config.hpp +++ b/core/src/config.hpp @@ -19,6 +19,7 @@ class Config : private Uncopyable { unsigned int timeWait; unsigned short timeout; unsigned short repeatWait; + unsigned short chunkSize; }; struct Log { diff --git a/core/src/general.hpp b/core/src/general.hpp index 7affc79..8aa59d8 100644 --- a/core/src/general.hpp +++ b/core/src/general.hpp @@ -309,6 +309,18 @@ inline BoolStr validateConfig(int argc, const char *argv[]) { return result; } + try { + configYaml["general"]["fakeUrl"].as<std::string>(); + configYaml["general"]["method"].as<std::string>(); + configYaml["general"]["timeWait"].as<unsigned int>(); + configYaml["general"]["timeout"].as<unsigned short>(); + configYaml["general"]["repeatWait"].as<unsigned short>(); + configYaml["general"]["chunkSize"].as<unsigned short>(); + } catch (const std::exception &e) { + result.message = std::string("Error in 'general' block: ") + e.what() + "\n"; + return result; + } + try { configYaml["log"]["logFile"].as<std::string>(); configYaml["log"]["logLevel"].as<std::string>(); diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index 85dada9..cdcb61d 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -18,11 +18,14 @@ general: # Defines the loop count which will try to repeat read from socket. # Same as timeWait repeatWait: 10 + # chunkSize: unsigned short(1-65,635) + # Defines the chunk size that you want to read from socket. + chunkSize: 512 # This block is to define log directives log: # logLevel: "INFO|TRACE|DEBUG" - logLevel: "INFO" + logLevel: "DEBUG" # logFile: "/var/log/nipo/nipo.log" # Path of log file logFile: "/var/log/nipovpn/nipovpn.log" From 9a26b01667bf5a49082f1fb5c67f106c121e945f Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Fri, 4 Oct 2024 15:41:28 +0200 Subject: [PATCH 04/11] problem with reading from socket when data is big --- core/src/agenthandler.cpp | 88 ++++++++++++++++++++++----------- core/src/agenthandler.hpp | 3 ++ core/src/config.cpp | 2 + core/src/config.hpp | 1 + core/src/general.hpp | 1 + core/src/http.cpp | 19 ++++++- core/src/http.hpp | 3 ++ core/src/serverhandler.cpp | 69 +++++++++++++++++++------- core/src/serverhandler.hpp | 4 +- core/src/tcpclient.cpp | 26 ++++++++-- core/src/tcpclient.hpp | 19 +------ core/src/tcpconnection.cpp | 52 ++++++++++--------- core/src/tcpconnection.hpp | 3 +- nipovpn/etc/nipovpn/config.yaml | 9 ++-- 14 files changed, 202 insertions(+), 97 deletions(-) diff --git a/core/src/agenthandler.cpp b/core/src/agenthandler.cpp index 1cd8470..643592c 100644 --- a/core/src/agenthandler.cpp +++ b/core/src/agenthandler.cpp @@ -14,7 +14,10 @@ AgentHandler::AgentHandler(boost::asio::streambuf &readBuffer, writeBuffer_(writeBuffer), request_(HTTP::create(config, log, readBuffer, uuid)), clientConnStr_(clientConnStr), - uuid_(uuid) {} + uuid_(uuid) { + FUCK("TCPClient END"); + end_ = false; +} AgentHandler::~AgentHandler() {} @@ -28,14 +31,12 @@ void AgentHandler::handle() { if (encryption.ok) { log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Encryption Done]", Log::Level::DEBUG); - std::string newReq( request_->genHttpPostReqString(encode64(encryption.message))); if (request_->detectType()) { log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Request] : " + request_->toString(), Log::Level::DEBUG); - if (request_->parsedHttpRequest().target().length() > 0) { log_->write("[" + to_string(uuid_) + "] [CONNECT] [SRC " + clientConnStr_ + "]" + " [DST " + boost::lexical_cast<std::string>( @@ -43,13 +44,10 @@ void AgentHandler::handle() { "]", Log::Level::INFO); } - if (!client_->socket().is_open() || request_->httpType() == HTTP::HttpType::http || request_->httpType() == HTTP::HttpType::connect) { boost::system::error_code ec; - ; - if (!client_->doConnect(config_->agent().serverIp, config_->agent().serverPort)) { log_->write(std::string("[" + to_string(uuid_) + "] [CONNECT] [ERROR] [To Server] [SRC ") + @@ -58,7 +56,6 @@ void AgentHandler::handle() { std::to_string(config_->agent().serverPort) + "]", Log::Level::INFO); } - if (ec) { log_->write(std::string("[" + to_string(uuid_) + "] [AgentHandler handle] Connection error: ") + ec.message(), @@ -68,43 +65,33 @@ void AgentHandler::handle() { } copyStringToStreambuf(newReq, readBuffer_); - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Request To Server] : \n" + newReq, Log::Level::DEBUG); - client_->doWrite(readBuffer_); client_->doRead(); - if (client_->readBuffer().size() > 0) { - if (request_->httpType() != HTTP::HttpType::connect) { - HTTP::pointer response = HTTP::create(config_, log_, client_->readBuffer(), uuid_); - - if (response->parseHttpResp()) { - log_->write( "[" + to_string(uuid_) + "] [AgentHandler handle] [Response] : " + response->restoString(), Log::Level::DEBUG); - - BoolStr decryption{false, std::string("FAILED")}; decryption = aes256Decrypt(decode64(boost::lexical_cast<std::string>( response->parsedHttpResponse().body())), config_->agent().token); - - + if (boost::lexical_cast<std::string>(response->parsedHttpResponse()[config_->general().chunkHeader]) == "yes") { + FUCK("AgentHandler END"); + end_ = true; + } if (decryption.ok) { - copyStringToStreambuf(decryption.message, writeBuffer_); log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Done]", Log::Level::DEBUG); } else { - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Failed] : [ " + decryption.message + "] ", Log::Level::DEBUG); @@ -114,7 +101,6 @@ void AgentHandler::handle() { client_->socket().close(); } } else { - log_->write( "[AgentHandler handle] [NOT HTTP Response] " "[Response] : " + @@ -122,21 +108,17 @@ void AgentHandler::handle() { Log::Level::DEBUG); } } else { - + end_ = true; log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Response to connect] : \n" + streambufToString(client_->readBuffer()), Log::Level::DEBUG); - - moveStreambuf(client_->readBuffer(), writeBuffer_); } } else { - client_->socket().close(); return; } } else { - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [NOT HTTP Request] [Request] : " + streambufToString(readBuffer_), Log::Level::DEBUG); @@ -145,7 +127,6 @@ void AgentHandler::handle() { return; } } else { - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Encryption Failed] : [ " + encryption.message + "] ", Log::Level::DEBUG); @@ -154,7 +135,58 @@ void AgentHandler::handle() { client_->socket().remote_endpoint().address().to_string() + ":" + std::to_string(client_->socket().remote_endpoint().port()) + "] ", Log::Level::INFO); + client_->socket().close(); + return; + } +} +void AgentHandler::continueRead() { + FUCK("AgentHandler::continueRead"); + std::lock_guard<std::mutex> lock(mutex_); + client_->doRead(); + if (client_->readBuffer().size() > 0) { + if (request_->httpType() != HTTP::HttpType::connect) { + HTTP::pointer response = + HTTP::create(config_, log_, client_->readBuffer(), uuid_); + if (response->parseHttpResp()) { + log_->write( + "[" + to_string(uuid_) + "] [AgentHandler handle] [Response] : " + response->restoString(), + Log::Level::DEBUG); + BoolStr decryption{false, std::string("FAILED")}; + decryption = + aes256Decrypt(decode64(boost::lexical_cast<std::string>( + response->parsedHttpResponse().body())), + config_->agent().token); + if (boost::lexical_cast<std::string>(response->parsedHttpResponse()[config_->general().chunkHeader]) == "yes") { + FUCK("AgentHandler continueRead END"); + end_ = true; + } + if (decryption.ok) { + copyStringToStreambuf(decryption.message, writeBuffer_); + log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Done]", Log::Level::DEBUG); + } else { + log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Failed] : [ " + + decryption.message + "] ", + Log::Level::DEBUG); + log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Failed] : " + + request_->toString(), + Log::Level::INFO); + client_->socket().close(); + } + } else { + log_->write( + "[AgentHandler handle] [NOT HTTP Response] " + "[Response] : " + + streambufToString(client_->readBuffer()), + Log::Level::DEBUG); + } + } else { + log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Response to connect] : \n" + + streambufToString(client_->readBuffer()), + Log::Level::DEBUG); + moveStreambuf(client_->readBuffer(), writeBuffer_); + } + } else { client_->socket().close(); return; } diff --git a/core/src/agenthandler.hpp b/core/src/agenthandler.hpp index 4812025..becbd8d 100644 --- a/core/src/agenthandler.hpp +++ b/core/src/agenthandler.hpp @@ -28,11 +28,14 @@ class AgentHandler : private Uncopyable { ~AgentHandler(); void handle(); + void continueRead(); inline const HTTP::pointer &request() & { return request_; } inline const HTTP::pointer &&request() && { return std::move(request_); } + bool end_; + private: AgentHandler(boost::asio::streambuf &readBuffer, boost::asio::streambuf &writeBuffer, diff --git a/core/src/config.cpp b/core/src/config.cpp index 2ce7705..769bf17 100644 --- a/core/src/config.cpp +++ b/core/src/config.cpp @@ -12,6 +12,7 @@ Config::Config(const RunMode &mode, const std::string &filePath) configYaml_["general"]["timeWait"].as<unsigned int>(), configYaml_["general"]["timeout"].as<unsigned short>(), configYaml_["general"]["repeatWait"].as<unsigned short>(), + configYaml_["general"]["chunkHeader"].as<std::string>(), configYaml_["general"]["chunkSize"].as<unsigned short>()}), log_({configYaml_["log"]["logLevel"].as<std::string>(), configYaml_["log"]["logFile"].as<std::string>()}), @@ -63,6 +64,7 @@ std::string Config::toString() const { << " timeWait: " << general_.timeWait << "\n" << " timeout: " << general_.timeout << "\n" << " repeatWait: " << general_.repeatWait << "\n" + << " chunkHeader: " << general_.chunkHeader << "\n" << " chunkSize: " << general_.chunkSize << "\n" << " Log :\n" << " logLevel: " << log_.level << "\n" diff --git a/core/src/config.hpp b/core/src/config.hpp index 7d1e8c6..cf6ba97 100644 --- a/core/src/config.hpp +++ b/core/src/config.hpp @@ -19,6 +19,7 @@ class Config : private Uncopyable { unsigned int timeWait; unsigned short timeout; unsigned short repeatWait; + std::string chunkHeader; unsigned short chunkSize; }; diff --git a/core/src/general.hpp b/core/src/general.hpp index 8aa59d8..ab6b820 100644 --- a/core/src/general.hpp +++ b/core/src/general.hpp @@ -315,6 +315,7 @@ inline BoolStr validateConfig(int argc, const char *argv[]) { configYaml["general"]["timeWait"].as<unsigned int>(); configYaml["general"]["timeout"].as<unsigned short>(); configYaml["general"]["repeatWait"].as<unsigned short>(); + configYaml["general"]["chunkHeader"].as<std::string>(); configYaml["general"]["chunkSize"].as<unsigned short>(); } catch (const std::exception &e) { result.message = std::string("Error in 'general' block: ") + e.what() + "\n"; diff --git a/core/src/http.cpp b/core/src/http.cpp index f736018..676309b 100644 --- a/core/src/http.cpp +++ b/core/src/http.cpp @@ -8,7 +8,9 @@ HTTP::HTTP(const std::shared_ptr<Config> &config, parsedHttpRequest_(), httpType_(HTTP::HttpType::https), parsedTlsRequest_{"", "", TlsTypes::TLSHandshake}, - uuid_(uuid) {} + uuid_(uuid) { + chunkHeader_ = "no"; +} HTTP::HTTP(const HTTP &http) : config_(http.config_), @@ -16,7 +18,9 @@ HTTP::HTTP(const HTTP &http) buffer_(http.buffer_), parsedHttpRequest_(http.parsedHttpRequest_), parsedTlsRequest_(http.parsedTlsRequest_), - uuid_(http.uuid_) {} + uuid_(http.uuid_) { + chunkHeader_ = "no"; +} HTTP::~HTTP() {} @@ -138,10 +142,21 @@ const std::string HTTP::genHttpPostReqString(const std::string &body) const { "Content-Type: application/x-www-form-urlencoded\r\n" + "\r\n" + body; } +const std::string HTTP::genHttpRestPostReqString() const { + return std::string(config_->general().method + " " + + config_->general().fakeUrl + " HTTP/" + + config_->agent().httpVersion + "\r\n") + + "Host: " + config_->general().fakeUrl + "\r\n" + + "User-Agent: " + config_->agent().userAgent + "\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + + "Rest: yes\r\n"; +} + const std::string HTTP::genHttpOkResString(const std::string &body) const { return std::string("HTTP/1.1 200 OK\r\n") + "Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Length: " + std::to_string(body.length()) + "\r\n" + + config_->general().chunkHeader + ": " + chunkHeader_ + "\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: no-cache\r\n" + "Pragma: no-cache\r\n" + "\r\n" + body; } diff --git a/core/src/http.hpp b/core/src/http.hpp index 30402a9..c165879 100644 --- a/core/src/http.hpp +++ b/core/src/http.hpp @@ -52,6 +52,8 @@ class HTTP { const std::string genHttpPostReqString(const std::string &body) const; + const std::string genHttpRestPostReqString() const; + const std::string genHttpOkResString(const std::string &body) const; inline const boost::beast::http::request<boost::beast::http::string_body> & @@ -76,6 +78,7 @@ class HTTP { const std::string toString() const; const std::string restoString() const; + std::string chunkHeader_; private: explicit HTTP(const std::shared_ptr<Config> &config, diff --git a/core/src/serverhandler.cpp b/core/src/serverhandler.cpp index f70ccbf..a1d097c 100644 --- a/core/src/serverhandler.cpp +++ b/core/src/serverhandler.cpp @@ -14,28 +14,22 @@ ServerHandler::ServerHandler(boost::asio::streambuf &readBuffer, writeBuffer_(writeBuffer), request_(HTTP::create(config, log, readBuffer, uuid)), clientConnStr_(clientConnStr), - uuid_(uuid) {} + uuid_(uuid) { end_ = false; } ServerHandler::~ServerHandler() {} void ServerHandler::handle() { std::lock_guard<std::mutex> lock(mutex_); - - if (request_->detectType()) { - log_->write( "[" + to_string(uuid_) + "] [ServerHandler handle] [Request From Agent] : " + request_->toString(), Log::Level::DEBUG); - - BoolStr decryption{false, std::string("FAILED")}; decryption = aes256Decrypt(decode64(boost::lexical_cast<std::string>( request_->parsedHttpRequest().body())), config_->agent().token); if (decryption.ok) { - log_->write( "[" + to_string(uuid_) + "] [ServerHandler handle] [Token Valid] : " + request_->toString(), Log::Level::DEBUG); @@ -43,14 +37,13 @@ void ServerHandler::handle() { std::string tempHexArrStr(tempHexArr.begin(), tempHexArr.end()); copyStringToStreambuf(tempHexArrStr, readBuffer_); - if (request_->detectType()) { log_->write( "[" + to_string(uuid_) + "] [ServerHandler handle] [Request] : " + request_->toString(), Log::Level::DEBUG); switch (request_->httpType()) { case HTTP::HttpType::connect: { - + end_ = true; boost::asio::streambuf tempBuff; std::iostream os(&tempBuff); if (client_->doConnect(request_->dstIP(), request_->dstPort())) { @@ -77,7 +70,6 @@ void ServerHandler::handle() { } break; case HTTP::HttpType::http: case HTTP::HttpType::https: { - if (request_->httpType() == HTTP::HttpType::http) { if (client_->doConnect(request_->dstIP(), request_->dstPort())) { log_->write("[" + to_string(uuid_) + "] [CONNECT] [SRC " + clientConnStr_ + "] [DST " + @@ -97,13 +89,17 @@ void ServerHandler::handle() { } client_->doWrite(readBuffer_); client_->doRead(); + end_ = client_->end_; if (client_->readBuffer().size() > 0) { - BoolStr encryption{false, std::string("FAILED")}; encryption = aes256Encrypt(streambufToString(client_->readBuffer()), config_->agent().token); if (encryption.ok) { + if (end_) { + FUCK("serverHandler END"); + request_->chunkHeader_ = "yes"; + } std::string newRes( request_->genHttpOkResString(encode64(encryption.message))); copyStringToStreambuf(newRes, writeBuffer_); @@ -116,12 +112,11 @@ void ServerHandler::handle() { } } } else { - log_->write( "[" + to_string(uuid_) + "] [ServerHandler handle] [Encryption " "Failed] : [ " + - decryption.message + "] ", + encryption.message + "] ", Log::Level::DEBUG); log_->write("[" + to_string(uuid_) + "] [ServerHandler handle] [Encryption Failed] : " + request_->toString(), @@ -129,14 +124,12 @@ void ServerHandler::handle() { client_->socket().close(); } } else { - client_->socket().close(); return; } } break; } } else { - log_->write("[" + to_string(uuid_) + "] [ServerHandler handle] [NOT HTTP Request] [Request] : " + streambufToString(readBuffer_), Log::Level::DEBUG); @@ -145,7 +138,6 @@ void ServerHandler::handle() { return; } } else { - log_->write("[" + to_string(uuid_) + "] [ServerHandler handle] [Decryption Failed] : [ " + decryption.message + "] ", Log::Level::DEBUG); @@ -157,7 +149,6 @@ void ServerHandler::handle() { return; } } else { - log_->write( "[" + to_string(uuid_) + "] [ServerHandler handle] [NOT HTTP Request From Agent] [Request] : " + streambufToString(readBuffer_), @@ -167,3 +158,47 @@ void ServerHandler::handle() { return; } } + +void ServerHandler::continueRead() { + FUCK("ServerHandler::continueRead"); + std::lock_guard<std::mutex> lock(mutex_); + client_->doRead(); + end_ = client_->end_; + if (client_->readBuffer().size() > 0) { + BoolStr encryption{false, std::string("FAILED")}; + encryption = + aes256Encrypt(streambufToString(client_->readBuffer()), + config_->agent().token); + if (encryption.ok) { + if (end_) { + FUCK("serverHandler continueRead END"); + request_->chunkHeader_ = "yes"; + } + std::string newRes( + request_->genHttpOkResString(encode64(encryption.message))); + copyStringToStreambuf(newRes, writeBuffer_); + if (request_->httpType() == HTTP::HttpType::http) { + client_->socket().close(); + } else { + if (request_->parsedTlsRequest().type == + HTTP::TlsTypes::ApplicationData) { + client_->socket().close(); + } + } + } else { + log_->write( + "[" + to_string(uuid_) + + "] [ServerHandler handle] [Encryption " + "Failed] : [ " + + encryption.message + "] ", + Log::Level::DEBUG); + log_->write("[" + to_string(uuid_) + "] [ServerHandler handle] [Encryption Failed] : " + + request_->toString(), + Log::Level::INFO); + client_->socket().close(); + } + } else { + client_->socket().close(); + return; + } +} \ No newline at end of file diff --git a/core/src/serverhandler.hpp b/core/src/serverhandler.hpp index 9e94626..d3363ab 100644 --- a/core/src/serverhandler.hpp +++ b/core/src/serverhandler.hpp @@ -28,10 +28,12 @@ class ServerHandler : private Uncopyable { ~ServerHandler(); void handle(); + void continueRead(); inline const HTTP::pointer &request() & { return request_; } inline const HTTP::pointer &&request() && { return std::move(request_); } + bool end_; private: explicit ServerHandler(boost::asio::streambuf &readBuffer, @@ -51,8 +53,6 @@ class ServerHandler : private Uncopyable { HTTP::pointer request_; const std::string &clientConnStr_; - boost::uuids::uuid uuid_; - std::mutex mutex_; }; diff --git a/core/src/tcpclient.cpp b/core/src/tcpclient.cpp index 06f71c3..f42610c 100644 --- a/core/src/tcpclient.cpp +++ b/core/src/tcpclient.cpp @@ -10,7 +10,9 @@ TCPClient::TCPClient(boost::asio::io_context &io_context, io_context_(io_context), socket_(io_context), resolver_(io_context), - timeout_(io_context) {} + timeout_(io_context) { + end_ = false; +} boost::asio::ip::tcp::socket &TCPClient::socket() { std::lock_guard<std::mutex> lock(mutex_); @@ -26,12 +28,10 @@ bool TCPClient::doConnect(const std::string &dstIP, const unsigned short &dstPort) { std::lock_guard<std::mutex> lock(mutex_); try { - log_->write("[" + to_string(uuid_) + "] [TCPClient doConnect] [DST " + dstIP + ":" + std::to_string(dstPort) + "]", Log::Level::DEBUG); - boost::system::error_code error_code; auto endpoint = resolver_.resolve(dstIP.c_str(), std::to_string(dstPort).c_str(), error_code); if (error_code) { @@ -93,8 +93,13 @@ void TCPClient::doWrite(boost::asio::streambuf &buffer) { } void TCPClient::doRead() { + FUCK("TCPClient::doRead"); + end_ = false; std::lock_guard<std::mutex> lock(mutex_); try { + unsigned short headerSize{0}; + if (config_->runMode() == RunMode::agent) + headerSize = 512; readBuffer_.consume(readBuffer_.size()); boost::system::error_code error; @@ -113,6 +118,9 @@ void TCPClient::doRead() { socketShutdown(); return; } + if (readBuffer_.size() >= config_->general().chunkSize + headerSize) { + break; + } if (socket_.available() == 0) break; resetTimeout(); boost::asio::read(socket_, readBuffer_, @@ -133,6 +141,18 @@ void TCPClient::doRead() { } timer.expires_after(std::chrono::milliseconds(config_->general().timeWait)); timer.wait(); + if (readBuffer_.size() >= config_->general().chunkSize + headerSize) { + FUCK(readBuffer_.size()); + FUCK("CHUNK END"); + break; + } + } + + FUCK(readBuffer_.size()); + + if (socket_.available() == 0) { + FUCK("TCPClient END"); + end_ = true; } if (readBuffer_.size() > 0) { diff --git a/core/src/tcpclient.hpp b/core/src/tcpclient.hpp index 9773bbd..bd6a1b8 100644 --- a/core/src/tcpclient.hpp +++ b/core/src/tcpclient.hpp @@ -14,50 +14,35 @@ class TCPClient : public boost::enable_shared_from_this<TCPClient> { public: using pointer = boost::shared_ptr<TCPClient>; - static pointer create(boost::asio::io_context &io_context, const std::shared_ptr<Config> &config, const std::shared_ptr<Log> &log) { return pointer(new TCPClient(io_context, config, log)); } - boost::asio::ip::tcp::socket &socket(); - void writeBuffer(boost::asio::streambuf &buffer); - inline boost::asio::streambuf &writeBuffer() & { return writeBuffer_; } inline boost::asio::streambuf &&writeBuffer() && { return std::move(writeBuffer_); } - inline boost::asio::streambuf &readBuffer() & { return readBuffer_; } inline boost::asio::streambuf &&readBuffer() && { return std::move(readBuffer_); } - bool doConnect(const std::string &dstIP, const unsigned short &dstPort); - void doWrite(boost::asio::streambuf &buffer); - void doRead(); - void socketShutdown(); - boost::uuids::uuid uuid_; + bool end_; private: explicit TCPClient(boost::asio::io_context &io_context, const std::shared_ptr<Config> &config, const std::shared_ptr<Log> &log); - - void resetTimeout(); - void cancelTimeout(); - void onTimeout(const boost::system::error_code &error); - - const std::shared_ptr<Config> &config_; const std::shared_ptr<Log> &log_; @@ -67,7 +52,5 @@ class TCPClient : public boost::enable_shared_from_this<TCPClient> { boost::asio::streambuf readBuffer_; boost::asio::ip::tcp::resolver resolver_; boost::asio::deadline_timer timeout_; - - mutable std::mutex mutex_; }; diff --git a/core/src/tcpconnection.cpp b/core/src/tcpconnection.cpp index 0486460..7b9faa9 100644 --- a/core/src/tcpconnection.cpp +++ b/core/src/tcpconnection.cpp @@ -12,6 +12,7 @@ TCPConnection::TCPConnection(boost::asio::io_context &io_context, timeout_(io_context), strand_(boost::asio::make_strand(io_context_)) { uuid_ = boost::uuids::random_generator()(); + end_ = false; } boost::asio::ip::tcp::socket &TCPConnection::socket() { @@ -113,6 +114,12 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { std::to_string(socket_.remote_endpoint().port()), uuid_); agentHandler_->handle(); + end_ = agentHandler_->end_; + if (writeBuffer_.size() > 0) { + doWrite(agentHandler_); + } else { + socketShutdown(); + } } else if (config_->runMode() == RunMode::server) { ServerHandler::pointer serverHandler_ = ServerHandler::create( readBuffer_, writeBuffer_, config_, log_, client_, @@ -120,12 +127,12 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { std::to_string(socket_.remote_endpoint().port()), uuid_); serverHandler_->handle(); - } - - if (writeBuffer_.size() > 0) { - doWrite(); - } else { - socketShutdown(); + end_ = serverHandler_->end_; + if (writeBuffer_.size() > 0) { + doWrite(serverHandler_); + } else { + socketShutdown(); + } } } } catch (std::exception &error) { @@ -136,7 +143,8 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { } } -void TCPConnection::doWrite() { +void TCPConnection::doWrite(auto handlerPointer) { + boost::system::error_code error; std::lock_guard<std::mutex> lock(mutex_); try { log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [DST " + @@ -145,11 +153,20 @@ void TCPConnection::doWrite() { "] [Bytes " + std::to_string(writeBuffer_.size()) + "] ", Log::Level::DEBUG); resetTimeout(); - boost::asio::async_write(socket_, writeBuffer_, - boost::asio::bind_executor(strand_, - [self = shared_from_this()](const boost::system::error_code &error, std::size_t /*bytes_transferred*/) { - self->handleWrite(error); - })); + boost::asio::write(socket_, writeBuffer_, error); + cancelTimeout(); + if (!error) { + if (end_) { + FUCK("tcpconnection END"); + doRead(); + } else { + handlerPointer->continueRead(); + } + } else { + log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [error] " + error.message(), + Log::Level::ERROR); + socketShutdown(); + } } catch (std::exception &error) { log_->write( std::string("[" + to_string(uuid_) + "] [TCPConnection doWrite] [catch] ") + error.what(), @@ -158,17 +175,6 @@ void TCPConnection::doWrite() { } } -void TCPConnection::handleWrite(const boost::system::error_code &error) { - cancelTimeout(); - if (!error) { - doRead(); - } else { - log_->write("[" + to_string(uuid_) + "] [TCPConnection handleWrite] [error] " + error.message(), - Log::Level::ERROR); - socketShutdown(); - } -} - void TCPConnection::resetTimeout() { if (!config_->general().timeout) return; diff --git a/core/src/tcpconnection.hpp b/core/src/tcpconnection.hpp index b7350cf..a3f3ff1 100644 --- a/core/src/tcpconnection.hpp +++ b/core/src/tcpconnection.hpp @@ -39,9 +39,10 @@ class TCPConnection : public boost::enable_shared_from_this<TCPConnection> { void doRead(); void handleRead(const boost::system::error_code &error, size_t bytes_transferred); + void doWrite(auto handlerPointer); void doWrite(); - void handleWrite(const boost::system::error_code &error); void socketShutdown(); + bool end_; private: explicit TCPConnection(boost::asio::io_context &io_context, diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index cdcb61d..d39429d 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -13,14 +13,17 @@ general: # timeout: unsigned short # Defines the timeout for I/O Operation in seconds. 0 indicates no timeout. # Useful to automatically close stalled connections. - timeout: 5 + timeout: 500 # repeatWait: unsigned short(1-65,635) # Defines the loop count which will try to repeat read from socket. # Same as timeWait repeatWait: 10 - # chunkSize: unsigned short(1-65,635) + # chunkHeader: String + # Defines the chunk header that you want to inform Agent/Server if it is end or not. + chunkHeader: "END" + # chunkSize: unsigned short(512-65,635) # Defines the chunk size that you want to read from socket. - chunkSize: 512 + chunkSize: 5120 # This block is to define log directives log: From c0aed5adce4a081eae77fb59903c16816775e8ca Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Wed, 9 Oct 2024 12:38:07 +0200 Subject: [PATCH 05/11] chunk done till end of handshake --- core/src/agenthandler.cpp | 26 +++++--- core/src/agenthandler.hpp | 2 +- core/src/serverhandler.cpp | 11 +-- core/src/serverhandler.hpp | 2 +- core/src/tcpclient.cpp | 7 +- core/src/tcpconnection.cpp | 115 +++++++++++++++++++++++++++----- core/src/tcpconnection.hpp | 6 +- nipovpn/etc/nipovpn/config.yaml | 4 +- 8 files changed, 126 insertions(+), 47 deletions(-) diff --git a/core/src/agenthandler.cpp b/core/src/agenthandler.cpp index 643592c..62a5e2c 100644 --- a/core/src/agenthandler.cpp +++ b/core/src/agenthandler.cpp @@ -15,8 +15,8 @@ AgentHandler::AgentHandler(boost::asio::streambuf &readBuffer, request_(HTTP::create(config, log, readBuffer, uuid)), clientConnStr_(clientConnStr), uuid_(uuid) { - FUCK("TCPClient END"); end_ = false; + connect_ = false; } AgentHandler::~AgentHandler() {} @@ -47,6 +47,7 @@ void AgentHandler::handle() { if (!client_->socket().is_open() || request_->httpType() == HTTP::HttpType::http || request_->httpType() == HTTP::HttpType::connect) { + connect_ = true; boost::system::error_code ec; if (!client_->doConnect(config_->agent().serverIp, config_->agent().serverPort)) { @@ -85,7 +86,6 @@ void AgentHandler::handle() { response->parsedHttpResponse().body())), config_->agent().token); if (boost::lexical_cast<std::string>(response->parsedHttpResponse()[config_->general().chunkHeader]) == "yes") { - FUCK("AgentHandler END"); end_ = true; } if (decryption.ok) { @@ -108,7 +108,7 @@ void AgentHandler::handle() { Log::Level::DEBUG); } } else { - end_ = true; + connect_ = true; log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Response to connect] : \n" + streambufToString(client_->readBuffer()), Log::Level::DEBUG); @@ -141,8 +141,12 @@ void AgentHandler::handle() { } void AgentHandler::continueRead() { - FUCK("AgentHandler::continueRead"); + FUCK("gentHandler::continueRead()"); std::lock_guard<std::mutex> lock(mutex_); + std::string newReq( + request_->genHttpRestPostReqString()); + copyStringToStreambuf(newReq, readBuffer_); + client_->doWrite(readBuffer_); client_->doRead(); if (client_->readBuffer().size() > 0) { if (request_->httpType() != HTTP::HttpType::connect) { @@ -150,7 +154,7 @@ void AgentHandler::continueRead() { HTTP::create(config_, log_, client_->readBuffer(), uuid_); if (response->parseHttpResp()) { log_->write( - "[" + to_string(uuid_) + "] [AgentHandler handle] [Response] : " + response->restoString(), + "[" + to_string(uuid_) + "] [AgentHandler continueRead handle] [Response] : " + response->restoString(), Log::Level::DEBUG); BoolStr decryption{false, std::string("FAILED")}; decryption = @@ -158,30 +162,30 @@ void AgentHandler::continueRead() { response->parsedHttpResponse().body())), config_->agent().token); if (boost::lexical_cast<std::string>(response->parsedHttpResponse()[config_->general().chunkHeader]) == "yes") { - FUCK("AgentHandler continueRead END"); end_ = true; } if (decryption.ok) { copyStringToStreambuf(decryption.message, writeBuffer_); - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Done]", Log::Level::DEBUG); + log_->write("[" + to_string(uuid_) + "] [AgentHandler continueRead handle] [Decryption Done]", Log::Level::DEBUG); } else { - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Failed] : [ " + + log_->write("[" + to_string(uuid_) + "] [AgentHandler continueRead handle] [Decryption Failed] : [ " + decryption.message + "] ", Log::Level::DEBUG); - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Decryption Failed] : " + + log_->write("[" + to_string(uuid_) + "] [AgentHandler continueRead handle] [Decryption Failed] : " + request_->toString(), Log::Level::INFO); client_->socket().close(); } } else { log_->write( - "[AgentHandler handle] [NOT HTTP Response] " + "[AgentHandler continueRead handle] [NOT HTTP Response] " "[Response] : " + streambufToString(client_->readBuffer()), Log::Level::DEBUG); } } else { - log_->write("[" + to_string(uuid_) + "] [AgentHandler handle] [Response to connect] : \n" + + connect_ = true; + log_->write("[" + to_string(uuid_) + "] [AgentHandler continueRead handle] [Response to connect] : \n" + streambufToString(client_->readBuffer()), Log::Level::DEBUG); moveStreambuf(client_->readBuffer(), writeBuffer_); diff --git a/core/src/agenthandler.hpp b/core/src/agenthandler.hpp index becbd8d..578cb7a 100644 --- a/core/src/agenthandler.hpp +++ b/core/src/agenthandler.hpp @@ -34,7 +34,7 @@ class AgentHandler : private Uncopyable { inline const HTTP::pointer &&request() && { return std::move(request_); } - bool end_; + bool end_, connect_; private: AgentHandler(boost::asio::streambuf &readBuffer, diff --git a/core/src/serverhandler.cpp b/core/src/serverhandler.cpp index a1d097c..c099649 100644 --- a/core/src/serverhandler.cpp +++ b/core/src/serverhandler.cpp @@ -14,7 +14,10 @@ ServerHandler::ServerHandler(boost::asio::streambuf &readBuffer, writeBuffer_(writeBuffer), request_(HTTP::create(config, log, readBuffer, uuid)), clientConnStr_(clientConnStr), - uuid_(uuid) { end_ = false; } + uuid_(uuid) { + end_ = false; + connect_ = false; +} ServerHandler::~ServerHandler() {} @@ -43,7 +46,7 @@ void ServerHandler::handle() { Log::Level::DEBUG); switch (request_->httpType()) { case HTTP::HttpType::connect: { - end_ = true; + connect_ = true; boost::asio::streambuf tempBuff; std::iostream os(&tempBuff); if (client_->doConnect(request_->dstIP(), request_->dstPort())) { @@ -97,7 +100,6 @@ void ServerHandler::handle() { config_->agent().token); if (encryption.ok) { if (end_) { - FUCK("serverHandler END"); request_->chunkHeader_ = "yes"; } std::string newRes( @@ -160,7 +162,7 @@ void ServerHandler::handle() { } void ServerHandler::continueRead() { - FUCK("ServerHandler::continueRead"); + FUCK("ServerHandler::continueRead()"); std::lock_guard<std::mutex> lock(mutex_); client_->doRead(); end_ = client_->end_; @@ -171,7 +173,6 @@ void ServerHandler::continueRead() { config_->agent().token); if (encryption.ok) { if (end_) { - FUCK("serverHandler continueRead END"); request_->chunkHeader_ = "yes"; } std::string newRes( diff --git a/core/src/serverhandler.hpp b/core/src/serverhandler.hpp index d3363ab..847bacd 100644 --- a/core/src/serverhandler.hpp +++ b/core/src/serverhandler.hpp @@ -33,7 +33,7 @@ class ServerHandler : private Uncopyable { inline const HTTP::pointer &request() & { return request_; } inline const HTTP::pointer &&request() && { return std::move(request_); } - bool end_; + bool end_, connect_; private: explicit ServerHandler(boost::asio::streambuf &readBuffer, diff --git a/core/src/tcpclient.cpp b/core/src/tcpclient.cpp index f42610c..dd18145 100644 --- a/core/src/tcpclient.cpp +++ b/core/src/tcpclient.cpp @@ -93,7 +93,7 @@ void TCPClient::doWrite(boost::asio::streambuf &buffer) { } void TCPClient::doRead() { - FUCK("TCPClient::doRead"); + FUCK("TCPClient::doRead()"); end_ = false; std::lock_guard<std::mutex> lock(mutex_); try { @@ -142,16 +142,11 @@ void TCPClient::doRead() { timer.expires_after(std::chrono::milliseconds(config_->general().timeWait)); timer.wait(); if (readBuffer_.size() >= config_->general().chunkSize + headerSize) { - FUCK(readBuffer_.size()); - FUCK("CHUNK END"); break; } } - FUCK(readBuffer_.size()); - if (socket_.available() == 0) { - FUCK("TCPClient END"); end_ = true; } diff --git a/core/src/tcpconnection.cpp b/core/src/tcpconnection.cpp index 7b9faa9..ef9549c 100644 --- a/core/src/tcpconnection.cpp +++ b/core/src/tcpconnection.cpp @@ -13,6 +13,7 @@ TCPConnection::TCPConnection(boost::asio::io_context &io_context, strand_(boost::asio::make_strand(io_context_)) { uuid_ = boost::uuids::random_generator()(); end_ = false; + connect_ = false; } boost::asio::ip::tcp::socket &TCPConnection::socket() { @@ -28,18 +29,22 @@ void TCPConnection::start() { void TCPConnection::doRead() { try { - readBuffer_.consume(readBuffer_.size()); - writeBuffer_.consume(writeBuffer_.size()); - resetTimeout(); - boost::asio::async_read( - socket_, readBuffer_, boost::asio::transfer_exactly(1), - boost::asio::bind_executor( - strand_, - boost::bind(&TCPConnection::handleRead, shared_from_this(), - boost::asio::placeholders::error, - boost::asio::placeholders:: - bytes_transferred))); - + if (!end_) { + readBuffer_.consume(readBuffer_.size()); + writeBuffer_.consume(writeBuffer_.size()); + resetTimeout(); + boost::asio::async_read( + socket_, readBuffer_, boost::asio::transfer_exactly(1), + boost::asio::bind_executor( + strand_, + boost::bind(&TCPConnection::handleRead, shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders:: + bytes_transferred))); + } else { + FUCK("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEND"); + socketShutdown(); + } } catch (std::exception &error) { log_->write(std::string("[" + to_string(uuid_) + "] [TCPConnection doRead] [catch] ") + error.what(), Log::Level::ERROR); @@ -49,9 +54,7 @@ void TCPConnection::doRead() { void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { try { - cancelTimeout(); - if (error) { if (error == boost::asio::error::eof) { log_->write( @@ -115,6 +118,7 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { uuid_); agentHandler_->handle(); end_ = agentHandler_->end_; + connect_ = agentHandler_->connect_; if (writeBuffer_.size() > 0) { doWrite(agentHandler_); } else { @@ -128,6 +132,7 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { uuid_); serverHandler_->handle(); end_ = serverHandler_->end_; + connect_ = serverHandler_->connect_; if (writeBuffer_.size() > 0) { doWrite(serverHandler_); } else { @@ -143,9 +148,81 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { } } +void TCPConnection::doReadRest() { + try { + FUCK("TCPConnection::doReadRest()"); + readBuffer_.consume(readBuffer_.size()); + boost::system::error_code error; + resetTimeout(); + + boost::asio::read(socket_, readBuffer_, boost::asio::transfer_at_least(1), + error); + cancelTimeout(); + + boost::asio::steady_timer timer(io_context_); + for (auto i = 0; i <= config_->general().repeatWait; i++) { + while (true) { + if (!socket_.is_open()) { + log_->write("[" + to_string(uuid_) + "] [TCPConnection doReadRest] Socket is not OPEN", + Log::Level::DEBUG); + socketShutdown(); + return; + } + if (socket_.available() == 0) break; + resetTimeout(); + boost::asio::read(socket_, readBuffer_, + boost::asio::transfer_at_least(1), error); + cancelTimeout(); + if (error == boost::asio::error::eof) { + log_->write("[" + to_string(uuid_) + "] [TCPConnection doReadRest] [EOF] Connection closed by peer.", + Log::Level::TRACE); + socketShutdown(); + return; + } else if (error) { + log_->write( + std::string("[" + to_string(uuid_) + "] [TCPConnection doReadRest] [error] ") + error.message(), + Log::Level::ERROR); + socketShutdown(); + return; + } + } + timer.expires_after(std::chrono::milliseconds(config_->general().timeWait)); + timer.wait(); + } + + if (readBuffer_.size() > 0) { + try { + + log_->write("[" + to_string(uuid_) + "] [TCPConnection doReadRest] [SRC " + + socket_.remote_endpoint().address().to_string() + ":" + + std::to_string(socket_.remote_endpoint().port()) + + "] [Bytes " + std::to_string(readBuffer_.size()) + "] ", + Log::Level::DEBUG); + log_->write("[" + to_string(uuid_) + "] [Read from] [SRC " + + socket_.remote_endpoint().address().to_string() + ":" + + std::to_string(socket_.remote_endpoint().port()) + + "] " + "[Bytes " + std::to_string(readBuffer_.size()) + + "] ", + Log::Level::TRACE); + } catch (std::exception &error) { + + log_->write( + std::string("[" + to_string(uuid_) + "] [TCPConnection doReadRest] [catch log] ") + error.what(), + Log::Level::DEBUG); + } + } else { + socketShutdown(); + return; + } + } catch (std::exception &error) { + log_->write(std::string("[" + to_string(uuid_) + "] [TCPConnection doReadRest] [catch] ") + error.what(), + Log::Level::ERROR); + socketShutdown(); + } +} + void TCPConnection::doWrite(auto handlerPointer) { boost::system::error_code error; - std::lock_guard<std::mutex> lock(mutex_); try { log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [DST " + socket_.remote_endpoint().address().to_string() + ":" + @@ -156,11 +233,13 @@ void TCPConnection::doWrite(auto handlerPointer) { boost::asio::write(socket_, writeBuffer_, error); cancelTimeout(); if (!error) { - if (end_) { - FUCK("tcpconnection END"); + if (end_ || connect_) { doRead(); } else { + if (config_->runMode() == RunMode::server) + doReadRest(); handlerPointer->continueRead(); + doWrite(handlerPointer); } } else { log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [error] " + error.message(), @@ -205,7 +284,7 @@ void TCPConnection::socketShutdown() { socket_.close(); } catch (std::exception &error) { log_->write( - std::string("[" + to_string(uuid_) + "] [TCPClient socketShutdown] [catch] ") + error.what(), + std::string("[" + to_string(uuid_) + "] [TCPConnection socketShutdown] [catch] ") + error.what(), Log::Level::DEBUG); } } \ No newline at end of file diff --git a/core/src/tcpconnection.hpp b/core/src/tcpconnection.hpp index a3f3ff1..d26b67e 100644 --- a/core/src/tcpconnection.hpp +++ b/core/src/tcpconnection.hpp @@ -12,8 +12,7 @@ class TCPConnection : public boost::enable_shared_from_this<TCPConnection> { public: using pointer = - boost::shared_ptr<TCPConnection>;// Define a type alias for a shared - // pointer to TCPConnection + boost::shared_ptr<TCPConnection>; static pointer create(boost::asio::io_context &io_context, const std::shared_ptr<Config> &config, @@ -39,10 +38,11 @@ class TCPConnection : public boost::enable_shared_from_this<TCPConnection> { void doRead(); void handleRead(const boost::system::error_code &error, size_t bytes_transferred); + void doReadRest(); void doWrite(auto handlerPointer); void doWrite(); void socketShutdown(); - bool end_; + bool end_, connect_; private: explicit TCPConnection(boost::asio::io_context &io_context, diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index d39429d..1620c65 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -13,7 +13,7 @@ general: # timeout: unsigned short # Defines the timeout for I/O Operation in seconds. 0 indicates no timeout. # Useful to automatically close stalled connections. - timeout: 500 + timeout: 10 # repeatWait: unsigned short(1-65,635) # Defines the loop count which will try to repeat read from socket. # Same as timeWait @@ -23,7 +23,7 @@ general: chunkHeader: "END" # chunkSize: unsigned short(512-65,635) # Defines the chunk size that you want to read from socket. - chunkSize: 5120 + chunkSize: 512 # This block is to define log directives log: From 432bc34e5b5fac09891314a00ad16d387501fc09 Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Thu, 10 Oct 2024 11:07:11 +0200 Subject: [PATCH 06/11] single request done --- core/src/tcpconnection.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/core/src/tcpconnection.cpp b/core/src/tcpconnection.cpp index ef9549c..91efa94 100644 --- a/core/src/tcpconnection.cpp +++ b/core/src/tcpconnection.cpp @@ -29,22 +29,17 @@ void TCPConnection::start() { void TCPConnection::doRead() { try { - if (!end_) { - readBuffer_.consume(readBuffer_.size()); - writeBuffer_.consume(writeBuffer_.size()); - resetTimeout(); - boost::asio::async_read( - socket_, readBuffer_, boost::asio::transfer_exactly(1), - boost::asio::bind_executor( - strand_, - boost::bind(&TCPConnection::handleRead, shared_from_this(), - boost::asio::placeholders::error, - boost::asio::placeholders:: - bytes_transferred))); - } else { - FUCK("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEND"); - socketShutdown(); - } + readBuffer_.consume(readBuffer_.size()); + writeBuffer_.consume(writeBuffer_.size()); + resetTimeout(); + boost::asio::async_read( + socket_, readBuffer_, boost::asio::transfer_exactly(1), + boost::asio::bind_executor( + strand_, + boost::bind(&TCPConnection::handleRead, shared_from_this(), + boost::asio::placeholders::error, + boost::asio::placeholders:: + bytes_transferred))); } catch (std::exception &error) { log_->write(std::string("[" + to_string(uuid_) + "] [TCPConnection doRead] [catch] ") + error.what(), Log::Level::ERROR); @@ -239,6 +234,7 @@ void TCPConnection::doWrite(auto handlerPointer) { if (config_->runMode() == RunMode::server) doReadRest(); handlerPointer->continueRead(); + end_ = handlerPointer->end_; doWrite(handlerPointer); } } else { From 47ddd936cbe14a4f0332c6ae7c5bc4a1854b1ce9 Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Sun, 13 Oct 2024 17:00:33 +0200 Subject: [PATCH 07/11] fix agent read, no need to read chunk by chunk in agent from server --- core/src/agenthandler.cpp | 1 - core/src/serverhandler.cpp | 1 - core/src/tcpclient.cpp | 11 +++------ core/src/tcpconnection.cpp | 40 ++++++++++++++++++--------------- nipovpn/etc/nipovpn/config.yaml | 4 ++-- 5 files changed, 27 insertions(+), 30 deletions(-) diff --git a/core/src/agenthandler.cpp b/core/src/agenthandler.cpp index 62a5e2c..8c6572f 100644 --- a/core/src/agenthandler.cpp +++ b/core/src/agenthandler.cpp @@ -141,7 +141,6 @@ void AgentHandler::handle() { } void AgentHandler::continueRead() { - FUCK("gentHandler::continueRead()"); std::lock_guard<std::mutex> lock(mutex_); std::string newReq( request_->genHttpRestPostReqString()); diff --git a/core/src/serverhandler.cpp b/core/src/serverhandler.cpp index c099649..c31474c 100644 --- a/core/src/serverhandler.cpp +++ b/core/src/serverhandler.cpp @@ -162,7 +162,6 @@ void ServerHandler::handle() { } void ServerHandler::continueRead() { - FUCK("ServerHandler::continueRead()"); std::lock_guard<std::mutex> lock(mutex_); client_->doRead(); end_ = client_->end_; diff --git a/core/src/tcpclient.cpp b/core/src/tcpclient.cpp index dd18145..9c360e1 100644 --- a/core/src/tcpclient.cpp +++ b/core/src/tcpclient.cpp @@ -93,14 +93,9 @@ void TCPClient::doWrite(boost::asio::streambuf &buffer) { } void TCPClient::doRead() { - FUCK("TCPClient::doRead()"); end_ = false; std::lock_guard<std::mutex> lock(mutex_); try { - unsigned short headerSize{0}; - if (config_->runMode() == RunMode::agent) - headerSize = 512; - readBuffer_.consume(readBuffer_.size()); boost::system::error_code error; resetTimeout(); @@ -118,7 +113,7 @@ void TCPClient::doRead() { socketShutdown(); return; } - if (readBuffer_.size() >= config_->general().chunkSize + headerSize) { + if (config_->runMode() == RunMode::server && readBuffer_.size() >= config_->general().chunkSize) { break; } if (socket_.available() == 0) break; @@ -141,12 +136,12 @@ void TCPClient::doRead() { } timer.expires_after(std::chrono::milliseconds(config_->general().timeWait)); timer.wait(); - if (readBuffer_.size() >= config_->general().chunkSize + headerSize) { + if (config_->runMode() == RunMode::server && readBuffer_.size() >= config_->general().chunkSize) { break; } } - if (socket_.available() == 0) { + if (config_->runMode() == RunMode::server && socket_.available() == 0) { end_ = true; } diff --git a/core/src/tcpconnection.cpp b/core/src/tcpconnection.cpp index 91efa94..99814d1 100644 --- a/core/src/tcpconnection.cpp +++ b/core/src/tcpconnection.cpp @@ -145,7 +145,6 @@ void TCPConnection::handleRead(const boost::system::error_code &error, size_t) { void TCPConnection::doReadRest() { try { - FUCK("TCPConnection::doReadRest()"); readBuffer_.consume(readBuffer_.size()); boost::system::error_code error; resetTimeout(); @@ -219,28 +218,33 @@ void TCPConnection::doReadRest() { void TCPConnection::doWrite(auto handlerPointer) { boost::system::error_code error; try { - log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [DST " + - socket_.remote_endpoint().address().to_string() + ":" + - std::to_string(socket_.remote_endpoint().port()) + - "] [Bytes " + std::to_string(writeBuffer_.size()) + "] ", - Log::Level::DEBUG); resetTimeout(); - boost::asio::write(socket_, writeBuffer_, error); - cancelTimeout(); - if (!error) { - if (end_ || connect_) { - doRead(); + if (writeBuffer_.size() > 0) { + log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [DST " + + socket_.remote_endpoint().address().to_string() + ":" + + std::to_string(socket_.remote_endpoint().port()) + + "] [Bytes " + std::to_string(writeBuffer_.size()) + "] ", + Log::Level::DEBUG); + boost::asio::write(socket_, writeBuffer_, error); + cancelTimeout(); + if (!error) { + if (end_ || connect_) { + doRead(); + } else { + if (config_->runMode() == RunMode::server) + doReadRest(); + handlerPointer->continueRead(); + end_ = handlerPointer->end_; + doWrite(handlerPointer); + } } else { - if (config_->runMode() == RunMode::server) - doReadRest(); - handlerPointer->continueRead(); - end_ = handlerPointer->end_; - doWrite(handlerPointer); + log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [error] " + error.message(), + Log::Level::ERROR); + socketShutdown(); } } else { - log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [error] " + error.message(), - Log::Level::ERROR); socketShutdown(); + return; } } catch (std::exception &error) { log_->write( diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index 1620c65..a8a926b 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -13,7 +13,7 @@ general: # timeout: unsigned short # Defines the timeout for I/O Operation in seconds. 0 indicates no timeout. # Useful to automatically close stalled connections. - timeout: 10 + timeout: 0 # repeatWait: unsigned short(1-65,635) # Defines the loop count which will try to repeat read from socket. # Same as timeWait @@ -23,7 +23,7 @@ general: chunkHeader: "END" # chunkSize: unsigned short(512-65,635) # Defines the chunk size that you want to read from socket. - chunkSize: 512 + chunkSize: 1024 # This block is to define log directives log: From 3c27e562ce8f15cd6ffefa92b72fbf3129f8f1ff Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Sun, 13 Oct 2024 17:22:34 +0200 Subject: [PATCH 08/11] add \r\n to end of http responses --- core/src/http.cpp | 4 ++-- nipovpn/etc/nipovpn/config.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/http.cpp b/core/src/http.cpp index 676309b..e4c9d5c 100644 --- a/core/src/http.cpp +++ b/core/src/http.cpp @@ -139,7 +139,7 @@ const std::string HTTP::genHttpPostReqString(const std::string &body) const { "User-Agent: " + config_->agent().userAgent + "\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Content-Length: " + std::to_string(body.length()) + "\r\n" + - "Content-Type: application/x-www-form-urlencoded\r\n" + "\r\n" + body; + "Content-Type: application/x-www-form-urlencoded\r\n" + "\r\n" + body + "\r\n"; } const std::string HTTP::genHttpRestPostReqString() const { @@ -158,7 +158,7 @@ const std::string HTTP::genHttpOkResString(const std::string &body) const { "Content-Length: " + std::to_string(body.length()) + "\r\n" + config_->general().chunkHeader + ": " + chunkHeader_ + "\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: no-cache\r\n" + - "Pragma: no-cache\r\n" + "\r\n" + body; + "Pragma: no-cache\r\n" + "\r\n" + body + "\r\n"; } void HTTP::setIPPort() { diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index a8a926b..bee6ce7 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -23,7 +23,7 @@ general: chunkHeader: "END" # chunkSize: unsigned short(512-65,635) # Defines the chunk size that you want to read from socket. - chunkSize: 1024 + chunkSize: 4096 # This block is to define log directives log: From 2f67f0b22194ca6e8c20d8e67094bf500dc44252 Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Sun, 13 Oct 2024 17:31:51 +0200 Subject: [PATCH 09/11] add trace log to tcpconnection dowrite --- core/src/tcpconnection.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/tcpconnection.cpp b/core/src/tcpconnection.cpp index 99814d1..bd4609a 100644 --- a/core/src/tcpconnection.cpp +++ b/core/src/tcpconnection.cpp @@ -225,6 +225,11 @@ void TCPConnection::doWrite(auto handlerPointer) { std::to_string(socket_.remote_endpoint().port()) + "] [Bytes " + std::to_string(writeBuffer_.size()) + "] ", Log::Level::DEBUG); + log_->write("[" + to_string(uuid_) + "] [Write To] [DST " + + socket_.remote_endpoint().address().to_string() + ":" + + std::to_string(socket_.remote_endpoint().port()) + + "] [Bytes " + std::to_string(writeBuffer_.size()) + "] ", + Log::Level::TRACE); boost::asio::write(socket_, writeBuffer_, error); cancelTimeout(); if (!error) { From 22b1a71021398a7272fc76595b4334b078d523f5 Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Sun, 13 Oct 2024 20:30:24 +0200 Subject: [PATCH 10/11] check socket status for error handling in tcpClient and tcpConnection --- core/src/tcpclient.cpp | 12 ++++++------ core/src/tcpconnection.cpp | 5 +++++ core/src/tcpconnection.hpp | 1 - nipovpn/etc/nipovpn/config.yaml | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/core/src/tcpclient.cpp b/core/src/tcpclient.cpp index 9c360e1..ed4557b 100644 --- a/core/src/tcpclient.cpp +++ b/core/src/tcpclient.cpp @@ -96,6 +96,12 @@ void TCPClient::doRead() { end_ = false; std::lock_guard<std::mutex> lock(mutex_); try { + if (!socket_.is_open()) { + log_->write("[" + to_string(uuid_) + "] [TCPClient doRead] Socket is not OPEN", + Log::Level::DEBUG); + return; + } + readBuffer_.consume(readBuffer_.size()); boost::system::error_code error; resetTimeout(); @@ -107,12 +113,6 @@ void TCPClient::doRead() { boost::asio::steady_timer timer(io_context_); for (auto i = 0; i <= config_->general().repeatWait; i++) { while (true) { - if (!socket_.is_open()) { - log_->write("[" + to_string(uuid_) + "] [TCPClient doRead] Socket is not OPEN", - Log::Level::DEBUG); - socketShutdown(); - return; - } if (config_->runMode() == RunMode::server && readBuffer_.size() >= config_->general().chunkSize) { break; } diff --git a/core/src/tcpconnection.cpp b/core/src/tcpconnection.cpp index bd4609a..82ae39c 100644 --- a/core/src/tcpconnection.cpp +++ b/core/src/tcpconnection.cpp @@ -218,6 +218,11 @@ void TCPConnection::doReadRest() { void TCPConnection::doWrite(auto handlerPointer) { boost::system::error_code error; try { + if (!socket_.is_open()) { + log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] Socket is not OPEN", + Log::Level::DEBUG); + return; + } resetTimeout(); if (writeBuffer_.size() > 0) { log_->write("[" + to_string(uuid_) + "] [TCPConnection doWrite] [DST " + diff --git a/core/src/tcpconnection.hpp b/core/src/tcpconnection.hpp index d26b67e..11c9552 100644 --- a/core/src/tcpconnection.hpp +++ b/core/src/tcpconnection.hpp @@ -40,7 +40,6 @@ class TCPConnection : public boost::enable_shared_from_this<TCPConnection> { size_t bytes_transferred); void doReadRest(); void doWrite(auto handlerPointer); - void doWrite(); void socketShutdown(); bool end_, connect_; diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index bee6ce7..949108b 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -13,7 +13,7 @@ general: # timeout: unsigned short # Defines the timeout for I/O Operation in seconds. 0 indicates no timeout. # Useful to automatically close stalled connections. - timeout: 0 + timeout: 10 # repeatWait: unsigned short(1-65,635) # Defines the loop count which will try to repeat read from socket. # Same as timeWait @@ -21,7 +21,7 @@ general: # chunkHeader: String # Defines the chunk header that you want to inform Agent/Server if it is end or not. chunkHeader: "END" - # chunkSize: unsigned short(512-65,635) + # chunkSize: unsigned short(512-65,535) # Defines the chunk size that you want to read from socket. chunkSize: 4096 From d8e5b559df3ee1681a53d350d46c53b3fe227d60 Mon Sep 17 00:00:00 2001 From: Morteza Bashsiz <morteza.bashsiz@gmail.com> Date: Mon, 14 Oct 2024 10:06:04 +0200 Subject: [PATCH 11/11] change default config file --- nipovpn/etc/nipovpn/config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nipovpn/etc/nipovpn/config.yaml b/nipovpn/etc/nipovpn/config.yaml index 949108b..38c5c0e 100644 --- a/nipovpn/etc/nipovpn/config.yaml +++ b/nipovpn/etc/nipovpn/config.yaml @@ -17,7 +17,7 @@ general: # repeatWait: unsigned short(1-65,635) # Defines the loop count which will try to repeat read from socket. # Same as timeWait - repeatWait: 10 + repeatWait: 3 # chunkHeader: String # Defines the chunk header that you want to inform Agent/Server if it is end or not. chunkHeader: "END" @@ -28,7 +28,7 @@ general: # This block is to define log directives log: # logLevel: "INFO|TRACE|DEBUG" - logLevel: "DEBUG" + logLevel: "TRACE" # logFile: "/var/log/nipo/nipo.log" # Path of log file logFile: "/var/log/nipovpn/nipovpn.log"