mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-08-26 18:20:27 +01:00
TCP server added and changes made to the HTTP server.
This commit is contained in:
parent
5ad9c8e740
commit
a505f5a692
5 changed files with 665 additions and 20 deletions
|
@ -33,6 +33,9 @@
|
|||
#include "Timestamp.h"
|
||||
#include "I18N.h"
|
||||
|
||||
#include "TCPServer.h"
|
||||
#include <pthread.h>
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace util
|
||||
|
@ -43,6 +46,7 @@ namespace util
|
|||
Daemon_Singleton_Private() {};
|
||||
~Daemon_Singleton_Private() {};
|
||||
|
||||
std::unique_ptr<i2p::tcp::TCPServer> tcpServer;
|
||||
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
||||
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
||||
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
||||
|
@ -67,7 +71,17 @@ namespace util
|
|||
DaemonDataDir = path;
|
||||
}
|
||||
|
||||
bool Daemon_Singleton::init(int argc, char* argv[]) {
|
||||
bool Daemon_Singleton::init(int argc, char* argv[])
|
||||
{
|
||||
this->onTcpServer = false;
|
||||
|
||||
if(argv[1])
|
||||
{
|
||||
std::string arg1(argv[1]);
|
||||
if(arg1 == "@:start")
|
||||
this->onTcpServer = true;
|
||||
}
|
||||
|
||||
return init(argc, argv, nullptr);
|
||||
}
|
||||
|
||||
|
@ -321,7 +335,7 @@ namespace util
|
|||
if (http) {
|
||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||
LogPrint(eLogInfo, "Daemon: Starting Webconsole at ", httpAddr, ":", httpPort);
|
||||
LogPrint(eLogInfo, "Daemon: Starting Webconsole at ", httpAddr, ":", httpPort);
|
||||
try
|
||||
{
|
||||
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
||||
|
@ -360,11 +374,20 @@ namespace util
|
|||
ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
||||
// Start Console I2PD.
|
||||
if(this->onTcpServer == true)
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: Starting TCP server (Demo.)");
|
||||
d.tcpServer = std::unique_ptr<i2p::tcp::TCPServer>(new i2p::tcp::TCPServer());
|
||||
d.tcpServer->Start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Daemon_Singleton::stop()
|
||||
{
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: Shutting down");
|
||||
LogPrint(eLogInfo, "Daemon: Stopping Client");
|
||||
i2p::client::context.Stop();
|
||||
|
@ -378,7 +401,6 @@ namespace util
|
|||
d.UPnP->Stop ();
|
||||
d.UPnP = nullptr;
|
||||
}
|
||||
|
||||
if (d.m_NTPSync)
|
||||
{
|
||||
d.m_NTPSync->Stop ();
|
||||
|
@ -393,7 +415,7 @@ namespace util
|
|||
LogPrint(eLogInfo, "Daemon: Stopping HTTP Server");
|
||||
d.httpServer->Stop();
|
||||
d.httpServer = nullptr;
|
||||
}
|
||||
}
|
||||
if (d.m_I2PControlService)
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: Stopping I2PControl");
|
||||
|
@ -402,7 +424,12 @@ namespace util
|
|||
}
|
||||
i2p::crypto::TerminateCrypto ();
|
||||
i2p::log::Logger().Stop();
|
||||
|
||||
|
||||
// Stop Console I2PD.
|
||||
LogPrint(eLogInfo, "Daemon: Starting TCP server (Demo.)");
|
||||
d.tcpServer->Stop();
|
||||
d.tcpServer->Printf();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,10 +29,10 @@ namespace util
|
|||
virtual void run () {};
|
||||
|
||||
virtual void setDataDir (std::string path);
|
||||
|
||||
|
||||
bool onTcpServer;
|
||||
bool isDaemon;
|
||||
bool running;
|
||||
|
||||
protected:
|
||||
|
||||
Daemon_Singleton ();
|
||||
|
@ -114,12 +114,11 @@ namespace util
|
|||
void run ();
|
||||
|
||||
private:
|
||||
|
||||
std::string pidfile;
|
||||
int pidFH;
|
||||
|
||||
public:
|
||||
|
||||
bool onTcpServer;
|
||||
int gracefulShutdownInterval; // in seconds
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -956,15 +956,7 @@ namespace http {
|
|||
void ShowI2PTunnels (std::stringstream& s)
|
||||
{
|
||||
std::string webroot; i2p::config::GetOption("http.webroot", webroot);
|
||||
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||
for (auto& it: i2p::client::context.GetClientTunnels ())
|
||||
{
|
||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||
s << it.second->GetName () << "</a> ⇐ ";
|
||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||
s << "</div>\r\n"<< std::endl;
|
||||
}
|
||||
s << "<b>" << tr("Client Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||
auto httpProxy = i2p::client::context.GetHttpProxy ();
|
||||
if (httpProxy)
|
||||
{
|
||||
|
@ -984,7 +976,18 @@ namespace http {
|
|||
s << "</div>\r\n"<< std::endl;
|
||||
}
|
||||
s << "</div>\r\n";
|
||||
|
||||
auto& clientTunnels = i2p::client::context.GetClientTunnels();
|
||||
if (!clientTunnels.empty ())
|
||||
{
|
||||
for (auto& it: clientTunnels)
|
||||
{
|
||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||
s << it.second->GetName () << "</a> ⇐ ";
|
||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||
s << "</div>\r\n"<< std::endl;
|
||||
}
|
||||
}
|
||||
auto& serverTunnels = i2p::client::context.GetServerTunnels ();
|
||||
if (!serverTunnels.empty ()) {
|
||||
s << "<br>\r\n<b>" << tr("Server Tunnels") << ":</b><br>\r\n<div class=\"list\">\r\n";
|
||||
|
|
543
daemon/TCPServer.cpp
Normal file
543
daemon/TCPServer.cpp
Normal file
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* Copyright (c) 2023, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
* See full license text in LICENSE file at top of project tree
|
||||
*/
|
||||
#include "TCPServer.h"
|
||||
#include <iostream>
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
//#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sstream>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstream>
|
||||
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "Base.h"
|
||||
#include "FS.h"
|
||||
#include "Log.h"
|
||||
#include "Config.h"
|
||||
#include "Tunnel.h"
|
||||
#include "Transports.h"
|
||||
#include "NetDb.hpp"
|
||||
#include "LeaseSet.h"
|
||||
#include "Destination.h"
|
||||
#include "RouterContext.h"
|
||||
#include "ClientContext.h"
|
||||
#include "Daemon.h"
|
||||
#include "util.h"
|
||||
#include "ECIESX25519AEADRatchetSession.h"
|
||||
#include "I18N.h"
|
||||
|
||||
#ifdef WIN32_APP
|
||||
#include "Win32App.h"
|
||||
#endif
|
||||
|
||||
// For image, style and info
|
||||
#include "version.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace tcp
|
||||
{
|
||||
// Private region.-------------------------------------------------------------------------------
|
||||
// Part: Connection.
|
||||
void TCPServer::_socker()
|
||||
{
|
||||
bzero((char*)&servAddr, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_addr.s_addr = inet_addr(IpAddress);
|
||||
servAddr.sin_port = htons(port);
|
||||
|
||||
serverSd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(serverSd < 0)
|
||||
{
|
||||
std::cerr << "[!] - Error establishing the server socket" << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPServer::_bind()
|
||||
{
|
||||
bindStatus = bind(serverSd, (struct sockaddr*) &servAddr, sizeof(servAddr));
|
||||
if(bindStatus < 0)
|
||||
{
|
||||
std::cerr << "[!] - Error binding socket to local address" << std::endl;
|
||||
codeStop = 2;
|
||||
}
|
||||
|
||||
std::cout << "[*] - Waiting for a client to connect..." << std::endl;
|
||||
listen(serverSd, 1);
|
||||
}
|
||||
|
||||
void TCPServer::_accept()
|
||||
{
|
||||
newSockAddrSize = sizeof(newSockAddr);
|
||||
newSd = accept(serverSd, (sockaddr *)&newSockAddr, &newSockAddrSize);
|
||||
|
||||
if(newSd < 0)
|
||||
{
|
||||
std::cerr << "[!] - Error accepting request from client!" << std::endl;
|
||||
codeStop = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "[*] - Connected with client!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TCPServer::_close()
|
||||
{
|
||||
std::cout << "[-] - Start close socket..." << std::endl;
|
||||
gettimeofday(&end1, NULL);
|
||||
close(newSd);
|
||||
close(serverSd);
|
||||
std::cout << "[-] - End close socket..." << std::endl;
|
||||
}
|
||||
//End part: Connection.
|
||||
// Part: Static.
|
||||
static void showUptime(std::stringstream& s, int seconds)
|
||||
{
|
||||
int num;
|
||||
|
||||
if ((num = seconds / 86400) > 0) {
|
||||
s << ntr("%d day", "%d days", num, num) << ", ";
|
||||
seconds -= num * 86400;
|
||||
}
|
||||
if ((num = seconds / 3600) > 0) {
|
||||
s << ntr("%d hour", "%d hours", num, num) << ", ";
|
||||
seconds -= num * 3600;
|
||||
}
|
||||
if ((num = seconds / 60) > 0) {
|
||||
s << ntr("%d minute", "%d minutes", num, num) << ", ";
|
||||
seconds -= num * 60;
|
||||
}
|
||||
s << ntr("%d second", "%d seconds", seconds, seconds);
|
||||
}
|
||||
|
||||
static void showStatus(std::stringstream& s, i2p::RouterStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case eRouterStatusOK: s << tr("OK."); break;
|
||||
case eRouterStatusTesting: s << tr("Testing."); break;
|
||||
case eRouterStatusFirewalled: s << tr("Firewalled."); break;
|
||||
case eRouterStatusUnknown: s << tr("Unknown."); break;
|
||||
case eRouterStatusProxy: s << tr("Proxy."); break;
|
||||
case eRouterStatusMesh: s << tr("Mesh."); break;
|
||||
default: s << tr("Unknown (default).");
|
||||
}
|
||||
}
|
||||
|
||||
static void showTraffic(std::stringstream& s, uint64_t bytes)
|
||||
{
|
||||
s << std::fixed << std::setprecision(2);
|
||||
auto numKBytes = (double) bytes / 1024;
|
||||
if (numKBytes < 1024)
|
||||
s << tr(/* tr: Kibibyte */ "%.2f KiB", numKBytes);
|
||||
else if (numKBytes < 1024 * 1024)
|
||||
s << tr(/* tr: Mebibyte */ "%.2f MiB", numKBytes / 1024);
|
||||
else
|
||||
s << tr(/* tr: Gibibyte */ "%.2f GiB", numKBytes / 1024 / 1024);
|
||||
}
|
||||
|
||||
template<typename Sessions>
|
||||
static void ShowTransportSessions (std::stringstream& s, const Sessions& sessions, const std::string name)
|
||||
{
|
||||
auto comp = [](typename Sessions::mapped_type a, typename Sessions::mapped_type b)
|
||||
{
|
||||
return a->GetRemoteEndpoint() < b->GetRemoteEndpoint();
|
||||
};
|
||||
|
||||
std::set<typename Sessions::mapped_type, decltype(comp)> sortedSessions(comp);
|
||||
for (const auto& it : sessions)
|
||||
{
|
||||
auto ret = sortedSessions.insert(it.second);
|
||||
if (!ret.second)
|
||||
LogPrint(eLogError, "TCPPServer: Duplicate remote endpoint detected: ", (*ret.first)->GetRemoteEndpoint());
|
||||
}
|
||||
|
||||
std::stringstream tmp_s, tmp_s6; uint16_t cnt = 0, cnt6 = 0;
|
||||
for (const auto& it: sortedSessions)
|
||||
{
|
||||
auto endpoint = it->GetRemoteEndpoint();
|
||||
|
||||
if (it && it->IsEstablished() && endpoint.address().is_v4 ())
|
||||
{
|
||||
tmp_s << i2p::data::GetIdentHashAbbreviation(it->GetRemoteIdentity()->GetIdentHash()) << ": "
|
||||
<< endpoint.address ().to_string () << ":" << endpoint.port ();
|
||||
|
||||
tmp_s << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]";
|
||||
|
||||
if (it->GetRelayTag ())
|
||||
tmp_s << " [itag:" << it->GetRelayTag () << "]";
|
||||
|
||||
if (it->GetSendQueueSize () > 0)
|
||||
tmp_s << " [queue:" << it->GetSendQueueSize () << "]";
|
||||
|
||||
tmp_s << std::endl;
|
||||
cnt++;
|
||||
}
|
||||
if (it && it->IsEstablished() && endpoint.address().is_v6 ())
|
||||
{
|
||||
tmp_s6 << i2p::data::GetIdentHashAbbreviation(it->GetRemoteIdentity()->GetIdentHash()) << ": "
|
||||
<< "[" << endpoint.address ().to_string () << "]:" << endpoint.port ();
|
||||
|
||||
tmp_s6 << " [" << it->GetNumSentBytes () << ":" << it->GetNumReceivedBytes () << "]";
|
||||
|
||||
if (it->GetRelayTag ())
|
||||
tmp_s6 << " [itag:" << it->GetRelayTag () << "]";
|
||||
|
||||
if (it->GetSendQueueSize () > 0)
|
||||
tmp_s6 << " [queue:" << it->GetSendQueueSize () << "]";
|
||||
|
||||
tmp_s6 << std::endl;
|
||||
cnt6++;
|
||||
}
|
||||
}
|
||||
if (!tmp_s.str().empty())
|
||||
{
|
||||
s << name << "(" << cnt << ")\n" << tmp_s.str() << "\n";
|
||||
}
|
||||
if (!tmp_s6.str().empty())
|
||||
{
|
||||
s << name << "v6 ( " << cnt6 << " )\n" << tmp_s6.str() << "\n";
|
||||
}
|
||||
}
|
||||
//End part: Loacal.
|
||||
//End private region.---------------------------------------------------------------------------
|
||||
// Publick region-------------------------------------------------------------------------------
|
||||
TCPServer::TCPServer(int _port)
|
||||
{
|
||||
port = _port;
|
||||
}
|
||||
|
||||
TCPServer::~TCPServer()
|
||||
{
|
||||
_close();
|
||||
//std::cout << "********Session********" << std::endl;
|
||||
//std::cout << "[i] - Bytes written: " << bytesWritten << " | Bytes read: " << bytesRead << std::endl;
|
||||
//std::cout << "[i] - Elapsed time: " << (end1.tv_sec - start1.tv_sec) << " secs." << std::endl;
|
||||
//std::cout << "[-] - Connection closed..." << std::endl;
|
||||
}
|
||||
|
||||
void TCPServer::Printf()
|
||||
{
|
||||
std::cout << "[*] - Address: 127.0.0.1 (default)" << std::endl;
|
||||
std::cout << "[*] - Port: " << port << std::endl;
|
||||
}
|
||||
|
||||
void TCPServer::Start()
|
||||
{
|
||||
while(codeStop == 0)
|
||||
{
|
||||
std::cout << "[i] - Init socket." << std::endl;
|
||||
_socker();
|
||||
|
||||
std::cout << "[i] - Start bind." << std::endl;
|
||||
_bind();
|
||||
|
||||
std::cout << "[i] - Server status: \"RUN\"." << std::endl;
|
||||
_accept();
|
||||
|
||||
start1.tv_sec = 0;
|
||||
end1.tv_sec = 0;
|
||||
|
||||
gettimeofday(&start1, NULL);
|
||||
|
||||
while(resetBit)
|
||||
{
|
||||
try
|
||||
{
|
||||
//receive a message from the client (listen)
|
||||
std::cout << "[i] - Awaiting client response..." << std::endl;
|
||||
memset(&msg, 0, sizeof(msg));//clear the buffer
|
||||
bytesRead += recv(newSd, (char*)&msg, sizeof(msg), 0);
|
||||
|
||||
if(!strcmp(msg, "@:clear") || !strcmp(msg, "@:cls"))
|
||||
{
|
||||
system("clear");
|
||||
strcpy(msg, "Bot -> test status: \"Server clear\" - ok.");
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
}
|
||||
else if(!strcmp(msg, "@:hi"))
|
||||
{
|
||||
std::cout << "[*] - Client send command \"hi\"." << std::endl;
|
||||
strcpy(msg, "Bot -> status msg: \"Good!\" ;)");
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
}
|
||||
else if(!strcmp(msg, "@:info"))
|
||||
{
|
||||
try
|
||||
{
|
||||
std::cout << "[*] - Client send command \"info\"." << std::endl;
|
||||
|
||||
std::stringstream s;
|
||||
|
||||
s << "\n\n---=== Base info I2PD. ===---\n";
|
||||
|
||||
// Output: Status.
|
||||
s << "\n";
|
||||
i2p::RouterStatus status = i2p::context.GetStatus();
|
||||
s << "> Status: ";
|
||||
showStatus(s, status);
|
||||
|
||||
// Output: Uptime.
|
||||
s << "\n";
|
||||
int uptime = i2p::context.GetUptime();
|
||||
s << "> Uptime: ";
|
||||
showUptime(s, uptime);
|
||||
|
||||
// Output: Tunnel creation success rate.
|
||||
s << "\n";
|
||||
s << "> Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate() << "%";
|
||||
|
||||
// Output: Received.
|
||||
s << "\n";
|
||||
s << "> Received: ";
|
||||
showTraffic(s, i2p::transport::transports.GetTotalReceivedBytes());
|
||||
s << " ("<<tr(/* tr: Kibibyte/s */ "%.2f KiB/s",(double)i2p::transport::transports.GetInBandwidth15s()/1024)<<").";
|
||||
|
||||
// Output: Sent.
|
||||
s << "\n";
|
||||
s << "> Sent: ";
|
||||
showTraffic (s, i2p::transport::transports.GetTotalSentBytes());
|
||||
s << " ("<<tr(/* tr: Kibibyte/s */ "%.2f KiB/s",(double)i2p::transport::transports.GetOutBandwidth15s()/1024)<<").";
|
||||
|
||||
// Output: Transit.
|
||||
s << "\n";
|
||||
s << "> Transit: ";
|
||||
showTraffic(s, i2p::transport::transports.GetTotalTransitTransmittedBytes());
|
||||
s << " ("<<tr(/* tr: Kibibyte/s */ "%.2f KiB/s",(double)i2p::transport::transports.GetTransitBandwidth15s()/1024)<<").";
|
||||
|
||||
// Output: Router Ident.
|
||||
s << "\n";
|
||||
s << "> Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64();
|
||||
|
||||
// Output: Base info.
|
||||
s << "\n";
|
||||
s << "> Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps");
|
||||
|
||||
s << "\n";
|
||||
s << "> Version: " << VERSION;
|
||||
|
||||
s << "\n";
|
||||
s << "> Routers: " << i2p::data::netdb.GetNumRouters() << ".";
|
||||
|
||||
s << "\n";
|
||||
s << "> Floodfills: " << i2p::data::netdb.GetNumFloodfills () << ".";
|
||||
|
||||
s << "\n";
|
||||
s << "> LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << ".";
|
||||
|
||||
size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels();
|
||||
clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels();
|
||||
size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels();
|
||||
|
||||
s << "\n";
|
||||
s << "> Client Tunnels: " << std::to_string(clientTunnelCount) << ".";;
|
||||
|
||||
s << "\n";
|
||||
s << "> Transit Tunnels: " << std::to_string(transitTunnelCount) << ".";
|
||||
|
||||
s << "\n\n---=== Info tunnelse I2PD. ===---\n\n";
|
||||
|
||||
s << "Client Tunnels:";
|
||||
auto httpProxy = i2p::client::context.GetHttpProxy();
|
||||
if(httpProxy)
|
||||
{
|
||||
s << "\n";
|
||||
auto& ident = httpProxy->GetLocalDestination()->GetIdentHash();
|
||||
s << "HTTP Proxy - " << i2p::client::context.GetAddressBook().ToAddress(ident);;
|
||||
}
|
||||
|
||||
auto socksProxy = i2p::client::context.GetSocksProxy();
|
||||
if(socksProxy)
|
||||
{
|
||||
s << "\n";
|
||||
auto& ident = socksProxy->GetLocalDestination()->GetIdentHash();
|
||||
s << "SOCKS Proxy - " << i2p::client::context.GetAddressBook().ToAddress(ident);
|
||||
}
|
||||
|
||||
auto& clientTunnels = i2p::client::context.GetClientTunnels();
|
||||
if(!clientTunnels.empty())
|
||||
{
|
||||
s << "\n";
|
||||
for (auto& it: clientTunnels)
|
||||
{
|
||||
auto& ident = it.second->GetLocalDestination()->GetIdentHash();
|
||||
s << it.second->GetName() << " - ";
|
||||
s << i2p::client::context.GetAddressBook().ToAddress(ident) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
auto& serverTunnels = i2p::client::context.GetServerTunnels();
|
||||
if(!serverTunnels.empty())
|
||||
{
|
||||
s << "\n";
|
||||
s << "Server Tunnels:" << "\n";
|
||||
for(auto& it: serverTunnels)
|
||||
{
|
||||
auto& ident = it.second->GetLocalDestination()->GetIdentHash();
|
||||
s << it.second->GetName() << " - ";
|
||||
s << i2p::client::context.GetAddressBook().ToAddress(ident);
|
||||
s << ":" << it.second->GetLocalPort() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
auto& clientForwards = i2p::client::context.GetClientForwards();
|
||||
if(!clientForwards.empty())
|
||||
{
|
||||
s << "\n";
|
||||
s << "Client Forwards:" << "\n";
|
||||
for (auto& it: clientForwards)
|
||||
{
|
||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||
s << it.second->GetName() << " - ";
|
||||
s << i2p::client::context.GetAddressBook().ToAddress(ident) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
auto& serverForwards = i2p::client::context.GetServerForwards();
|
||||
if(!serverForwards.empty())
|
||||
{
|
||||
s << "\n";
|
||||
s << "Server Forwards:\n";
|
||||
for(auto& it: serverForwards)
|
||||
{
|
||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||
s << it.second->GetName() << " - ";
|
||||
s << i2p::client::context.GetAddressBook().ToAddress(ident) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Convert and send msg.
|
||||
const std::string tmp = s.str();
|
||||
strcpy(msg, tmp.c_str());
|
||||
//std::cout << "[i] - " << msg;
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
}
|
||||
catch(const char* msg)
|
||||
{
|
||||
std::cout << msg << std::endl;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(msg, "@:tr"))
|
||||
{
|
||||
std::cout << "[*] - Client send command \"transport\"." << std::endl;
|
||||
std::stringstream s;
|
||||
s << "\n\n---=== Transport info I2PD. ===---\n";
|
||||
|
||||
auto ntcp2Server = i2p::transport::transports.GetNTCP2Server();
|
||||
if (ntcp2Server)
|
||||
{
|
||||
auto sessions = ntcp2Server->GetNTCP2Sessions();
|
||||
if (!sessions.empty ())
|
||||
ShowTransportSessions(s, sessions, "NTCP2");
|
||||
}
|
||||
auto ssu2Server = i2p::transport::transports.GetSSU2Server();
|
||||
if (ssu2Server)
|
||||
{
|
||||
auto sessions = ssu2Server->GetSSU2Sessions();
|
||||
if (!sessions.empty())
|
||||
ShowTransportSessions(s, sessions, "SSU2");
|
||||
}
|
||||
|
||||
// Convert and send msg.
|
||||
const std::string tmp = s.str();
|
||||
strcpy(msg, tmp.c_str());
|
||||
//std::cout << "[i] - " << msg << std::endl;
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
}
|
||||
else if(!strcmp(msg, "@:?"))
|
||||
{
|
||||
std::stringstream s;
|
||||
std::cout << "\n[*] - Client send command \"call helper\"." << std::endl;
|
||||
s << "\nHelper server v0.0.2\n";
|
||||
s << "@:info - Output base info about i2pd router.\n";
|
||||
s << "@:tr - Output info transport i2pd.\n";
|
||||
s << "@:exit - close console i2pd client.\n";
|
||||
s << "@:stop - kill i2pd service and exit.\n";
|
||||
s << "[+] - End help.";
|
||||
|
||||
const std::string tmp = s.str();
|
||||
strcpy(msg, tmp.c_str());
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
}
|
||||
else if(!strcmp(msg, "@:stop"))
|
||||
{
|
||||
std::cout << "[*] - Client send command \"stop\"." << std::endl;
|
||||
strcpy(msg, "Bot -> Server is stop.");
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
codeStop = 1;
|
||||
system("killall -s 9 ./i2pd");
|
||||
break;
|
||||
}
|
||||
else if(strcmp(msg, ""))
|
||||
{
|
||||
std::cout << "[*] - Client send command: " << std::endl;
|
||||
strcpy(msg, "Bot -> command status: \"Bad!\" :(");
|
||||
bytesWritten += send(newSd, (char*)&msg, strlen(msg), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "[!] - Disconnecting from the client!" << std::endl;
|
||||
std::cout << "[-] - Restart server..." << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
//Output send msg (side server).
|
||||
//std::cout << "[>] - Server send: " << msg << std::endl;
|
||||
}
|
||||
catch(const char* msg)
|
||||
{
|
||||
std::cout << "[!] - Disconnecting from the client." << std::endl;
|
||||
std::cout << msg << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_close();
|
||||
|
||||
if(codeStop >= 1)
|
||||
{
|
||||
std::cout << "[!] - Exit TCP server... \n" << "Stop code = " << codeStop << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TCPServer::Stop()
|
||||
{
|
||||
codeStop = 1;
|
||||
resetBit = false;
|
||||
std::cout << "[-] - Call distruct TCPServer, stop." << std::endl;
|
||||
_close();
|
||||
}
|
||||
|
||||
int TCPServer::GetCodeStop()
|
||||
{
|
||||
return codeStop;
|
||||
}
|
||||
} // tcp
|
||||
} // i2p
|
73
daemon/TCPServer.h
Normal file
73
daemon/TCPServer.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2023, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
* See full license text in LICENSE file at top of project tree
|
||||
*/
|
||||
|
||||
#ifndef TCP_SERVER_H__
|
||||
#define TCP_SERVER_H__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <boost/asio.hpp>
|
||||
#include <sstream>
|
||||
#include "HTTP.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace tcp
|
||||
{
|
||||
|
||||
class TCPServer
|
||||
{
|
||||
private:
|
||||
const char *IpAddress = "127.0.0.1";
|
||||
int num = 1;
|
||||
int port = 49151;
|
||||
char msg[8192];
|
||||
bool resetBit = true;
|
||||
int codeStop = 0;
|
||||
|
||||
sockaddr_in servAddr;
|
||||
int serverSd;
|
||||
int bindStatus;
|
||||
|
||||
sockaddr_in newSockAddr;
|
||||
socklen_t newSockAddrSize;
|
||||
int newSd;
|
||||
|
||||
struct timeval start1;
|
||||
struct timeval end1;
|
||||
|
||||
int bytesRead = 0;
|
||||
int bytesWritten = 0;
|
||||
|
||||
void _socker();
|
||||
void _bind();
|
||||
void _accept();
|
||||
void _recv();
|
||||
void _send();
|
||||
void _close();
|
||||
|
||||
public:
|
||||
TCPServer(int _port);
|
||||
TCPServer(){};
|
||||
~TCPServer();
|
||||
|
||||
void Printf();
|
||||
void Start();
|
||||
void Run();
|
||||
void Stop();
|
||||
int GetCodeStop();
|
||||
};
|
||||
|
||||
} // tcp
|
||||
} // i2p
|
||||
#endif /* TCP_SERVER_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue