From b791a6a348f415ed9ecdbd93f852b99ebdca1d43 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Mon, 31 Jul 2017 07:36:38 +0800 Subject: [PATCH 01/81] qt ui - status buttons done --- qt/i2pd_qt/i2pd_qt.pro | 3 +- qt/i2pd_qt/mainwindow.cpp | 27 ++++++--- qt/i2pd_qt/mainwindow.h | 4 ++ qt/i2pd_qt/mainwindow.ui | 78 +++++++++++++++++++++----- qt/i2pd_qt/statusbuttons.ui | 109 ++++++++++++++++++++++++++++++++++++ 5 files changed, 199 insertions(+), 22 deletions(-) create mode 100644 qt/i2pd_qt/statusbuttons.ui diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 66839ff5..ed9ffd2e 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -174,7 +174,8 @@ INCLUDEPATH += ../../daemon INCLUDEPATH += . FORMS += mainwindow.ui \ - tunnelform.ui + tunnelform.ui \ + statusbuttons.ui LIBS += -lz diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 9d312fa0..a4afe6a3 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,5 +1,6 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include "ui_statusbuttons.h" #include #include #include @@ -28,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent) : ,quitting(false) #endif ,ui(new Ui::MainWindow) + ,statusButtonsUI(new Ui::StatusButtonsForm) ,i2pController(nullptr) ,configItems() ,datadir() @@ -37,12 +39,16 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); + statusButtonsUI->setupUi(ui->statusButtonsPane); + ui->statusButtonsPane->setFixedSize(172,300); + ui->verticalLayout->setGeometry(QRect(0,0,172,ui->verticalLayout->geometry().height())); + ui->statusButtonsPane->adjustSize(); + ui->centralWidget->adjustSize(); setWindowTitle(QApplication::translate("AppTitle","I2PD")); //TODO handle resizes and change the below into resize() call - setFixedSize(width(), 480); - ui->centralWidget->setMinimumHeight(480); - ui->centralWidget->setMaximumHeight(480); + setFixedSize(width(), 550); + ui->centralWidget->setFixedHeight(550); onResize(); ui->stackedWidget->setCurrentIndex(0); @@ -70,6 +76,7 @@ MainWindow::MainWindow(QWidget *parent) : #endif QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusPage())); + setStatusButtonsVisible(true); QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage())); QObject::connect(ui->tunnelsPagePushButton, SIGNAL(released()), this, SLOT(showTunnelsPage())); @@ -226,11 +233,15 @@ MainWindow::MainWindow(QWidget *parent) : //QMetaObject::connectSlotsByName(this); } -void MainWindow::showStatusPage(){ui->stackedWidget->setCurrentIndex(0);} -void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(1);} -void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(2);} -void MainWindow::showRestartPage(){ui->stackedWidget->setCurrentIndex(3);} -void MainWindow::showQuitPage(){ui->stackedWidget->setCurrentIndex(4);} +void MainWindow::showStatusPage(){ui->stackedWidget->setCurrentIndex(0);setStatusButtonsVisible(true);} +void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(1);setStatusButtonsVisible(false);} +void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(2);setStatusButtonsVisible(false);} +void MainWindow::showRestartPage(){ui->stackedWidget->setCurrentIndex(3);setStatusButtonsVisible(false);} +void MainWindow::showQuitPage(){ui->stackedWidget->setCurrentIndex(4);setStatusButtonsVisible(false);} + +void MainWindow::setStatusButtonsVisible(bool visible) { + ui->statusButtonsPane->setVisible(visible); +} //TODO void MainWindow::resizeEvent(QResizeEvent *event) diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 05cb7151..fbadf83e 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -307,6 +307,7 @@ public: namespace Ui { class MainWindow; +class StatusButtonsForm; } using namespace i2p::client; @@ -359,6 +360,7 @@ private: #endif Ui::MainWindow* ui; + Ui::StatusButtonsForm* statusButtonsUI; i2p::qt::Controller* i2pController; @@ -369,6 +371,8 @@ protected: void resizeEvent(QResizeEvent* event); void onResize(); + void setStatusButtonsVisible(bool visible); + QList configItems; NonGUIOptionItem* logOption; NonGUIOptionItem* daemonOption; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 0b3071e9..8fb9ffc1 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -6,10 +6,22 @@ 0 0 - 816 - 516 + 904 + 550 + + + 904 + 0 + + + + + 950 + 16777215 + + MainWindow @@ -22,14 +34,14 @@ - 0 - 516 + 904 + 550 16777215 - 516 + 550 @@ -37,19 +49,27 @@ 10 10 - 796 - 496 + 931 + 498 - QLayout::SetDefaultConstraint + QLayout::SetMaximumSize - + QLayout::SetMinimumSize + + + 0 + 0 + 170 + 496 + + @@ -60,6 +80,22 @@ + + + + + 0 + 0 + + + + + 172 + 0 + + + + @@ -100,6 +136,22 @@ + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 172 + 0 + + + + @@ -136,7 +188,7 @@ - 4 + 0 @@ -231,8 +283,8 @@ 0 0 - 679 - 3000 + 684 + 426 @@ -247,7 +299,7 @@ 10 10 679 - 3000 + 3052 diff --git a/qt/i2pd_qt/statusbuttons.ui b/qt/i2pd_qt/statusbuttons.ui new file mode 100644 index 00000000..79461cd4 --- /dev/null +++ b/qt/i2pd_qt/statusbuttons.ui @@ -0,0 +1,109 @@ + + + StatusButtonsForm + + + + 0 + 0 + 170 + 295 + + + + + 0 + 0 + + + + + 170 + 295 + + + + Form + + + + + 20 + 0 + 151 + 301 + + + + + QLayout::SetDefaultConstraint + + + + + Main page + + + + + + + Router commands + + + + + + + Local destinations + + + + + + + Leasesets + + + + + + + Tunnels + + + + + + + Transit tunnels + + + + + + + Transports + + + + + + + I2P tunnels + + + + + + + SAM sessions + + + + + + + + + From 978bb47b92f229b30475c742bffcb343524e93f9 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Mon, 31 Jul 2017 07:39:22 +0800 Subject: [PATCH 02/81] qt ui - settings buttons renamed to *Settings --- qt/i2pd_qt/mainwindow.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 8fb9ffc1..7c1067b4 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -102,7 +102,7 @@ true - Settings + General Settings @@ -112,7 +112,7 @@ true - Tunnels + Tunnels Settings From 7d3a8185656ad37bacde2dd4723c99d44fbbd6ef Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Mon, 31 Jul 2017 08:00:48 +0800 Subject: [PATCH 03/81] qt ui - laid out better --- qt/i2pd_qt/mainwindow.ui | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 7c1067b4..afbef9a3 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -35,7 +35,7 @@ 904 - 550 + 0 @@ -50,7 +50,7 @@ 10 10 931 - 498 + 715 @@ -102,7 +102,7 @@ true - General Settings + General settings @@ -112,7 +112,7 @@ true - Tunnels Settings + Tunnels settings @@ -170,7 +170,7 @@ - + 0 0 @@ -178,17 +178,17 @@ 0 - 496 + 528 16777215 - 496 + 713 - 0 + 2 @@ -197,7 +197,7 @@ 0 0 686 - 496 + 531 @@ -245,12 +245,12 @@ 0 0 706 - 461 + 531 - QLayout::SetMinAndMaxSize + QLayout::SetMaximumSize @@ -284,7 +284,7 @@ 0 0 684 - 426 + 496 @@ -3046,7 +3046,7 @@ Comma separated list of base64 identities: 0 0 706 - 461 + 531 @@ -3110,7 +3110,7 @@ Comma separated list of base64 identities: - 0 + -18 0 699 425 From a79f614e12b2c7b7bb4fb2716d09b5abe896aca7 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Mon, 31 Jul 2017 09:58:54 +0800 Subject: [PATCH 04/81] qt ui - now pixel perfect buttons --- qt/i2pd_qt/mainwindow.cpp | 8 ++--- qt/i2pd_qt/mainwindow.ui | 8 ++--- qt/i2pd_qt/statusbuttons.ui | 64 ++++++++++++++++++++++++++++++++++--- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index a4afe6a3..840f5b5b 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -40,10 +40,10 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); statusButtonsUI->setupUi(ui->statusButtonsPane); - ui->statusButtonsPane->setFixedSize(172,300); - ui->verticalLayout->setGeometry(QRect(0,0,172,ui->verticalLayout->geometry().height())); - ui->statusButtonsPane->adjustSize(); - ui->centralWidget->adjustSize(); + ui->statusButtonsPane->setFixedSize(171,300); + ui->verticalLayout->setGeometry(QRect(0,0,171,ui->verticalLayout->geometry().height())); + //ui->statusButtonsPane->adjustSize(); + //ui->centralWidget->adjustSize(); setWindowTitle(QApplication::translate("AppTitle","I2PD")); //TODO handle resizes and change the below into resize() call diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index afbef9a3..60aacbe2 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -83,7 +83,7 @@ - + 0 0 @@ -146,7 +146,7 @@ - 172 + 171 0 @@ -260,7 +260,7 @@ - Settings + General settings @@ -3061,7 +3061,7 @@ Comma separated list of base64 identities: - Tunnels + Tunnels settings diff --git a/qt/i2pd_qt/statusbuttons.ui b/qt/i2pd_qt/statusbuttons.ui index 79461cd4..edf5a90c 100644 --- a/qt/i2pd_qt/statusbuttons.ui +++ b/qt/i2pd_qt/statusbuttons.ui @@ -6,7 +6,7 @@ 0 0 - 170 + 171 295 @@ -18,7 +18,7 @@ - 170 + 171 295 @@ -28,10 +28,10 @@ - 20 + 21 0 - 151 - 301 + 171 + 300 @@ -40,6 +40,12 @@ + + + 150 + 16777215 + + Main page @@ -47,6 +53,12 @@ + + + 150 + 16777215 + + Router commands @@ -54,6 +66,12 @@ + + + 150 + 16777215 + + Local destinations @@ -61,6 +79,12 @@ + + + 150 + 16777215 + + Leasesets @@ -68,6 +92,12 @@ + + + 150 + 16777215 + + Tunnels @@ -75,6 +105,12 @@ + + + 150 + 16777215 + + Transit tunnels @@ -82,6 +118,12 @@ + + + 150 + 16777215 + + Transports @@ -89,6 +131,12 @@ + + + 150 + 16777215 + + I2P tunnels @@ -96,6 +144,12 @@ + + + 150 + 16777215 + + SAM sessions From 163cbcb89db5a564c9e782bf69ac0d1d1e1ce640 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 2 Aug 2017 02:40:11 +0800 Subject: [PATCH 05/81] qt ui - status main page now works --- daemon/HTTPServer.cpp | 60 ++++++++++++++------------- daemon/HTTPServer.h | 3 ++ qt/i2pd_qt/i2pd_qt.pro | 6 ++- qt/i2pd_qt/mainwindow.cpp | 66 +++++++++++++++++++++++++++++- qt/i2pd_qt/mainwindow.h | 22 ++++++++-- qt/i2pd_qt/mainwindow.ui | 62 ++++++++++++++-------------- qt/i2pd_qt/textbrowsertweaked1.cpp | 6 +++ qt/i2pd_qt/textbrowsertweaked1.h | 22 ++++++++++ 8 files changed, 180 insertions(+), 67 deletions(-) create mode 100644 qt/i2pd_qt/textbrowsertweaked1.cpp create mode 100644 qt/i2pd_qt/textbrowsertweaked1.h diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 52feeb10..1f7dbc7b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -185,7 +185,7 @@ namespace http { s << "ERROR: " << string << "
\r\n"; } - static void ShowStatus (std::stringstream& s) + void ShowStatus (std::stringstream& s, bool includeHiddenContent) { s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); @@ -233,33 +233,35 @@ namespace http { s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
\r\n\r\n

\r\n"; - s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; - s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; - s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; - s << "Our external address:" << "
\r\n" ; - for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) - { - switch (address->transportStyle) - { - case i2p::data::RouterInfo::eTransportNTCP: - if (address->host.is_v6 ()) - s << "NTCP6  "; - else - s << "NTCP  "; - break; - case i2p::data::RouterInfo::eTransportSSU: - if (address->host.is_v6 ()) - s << "SSU6     "; - else - s << "SSU     "; - break; - default: - s << "Unknown  "; - } - s << address->host.to_string() << ":" << address->port << "
\r\n"; - } - s << "

\r\n
\r\n"; - s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; + if(includeHiddenContent) { + s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; + s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; + s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; + s << "Our external address:" << "
\r\n" ; + for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) + { + switch (address->transportStyle) + { + case i2p::data::RouterInfo::eTransportNTCP: + if (address->host.is_v6 ()) + s << "NTCP6  "; + else + s << "NTCP  "; + break; + case i2p::data::RouterInfo::eTransportSSU: + if (address->host.is_v6 ()) + s << "SSU6     "; + else + s << "SSU     "; + break; + default: + s << "Unknown  "; + } + s << address->host.to_string() << ":" << address->port << "
\r\n"; + } + } + s << "

\r\n\r\n"; + s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; @@ -797,7 +799,7 @@ namespace http { } else if (req.uri.find("cmd=") != std::string::npos) { HandleCommand (req, res, s); } else { - ShowStatus (s); + ShowStatus (s, true); res.add_header("Refresh", "10"); } ShowPageTail (s); diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index ec56e08a..edff1bf3 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "HTTP.h" namespace i2p @@ -75,6 +76,8 @@ namespace http boost::asio::io_service::work m_Work; boost::asio::ip::tcp::acceptor m_Acceptor; }; + + void ShowStatus (std::stringstream& s, bool includeHiddenContent); } // http } // i2p diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index ed9ffd2e..918f0230 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -87,7 +87,8 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../daemon/i2pd.cpp \ ../../daemon/I2PControl.cpp \ ../../daemon/UnixDaemon.cpp \ - ../../daemon/UPnP.cpp + ../../daemon/UPnP.cpp \ + textbrowsertweaked1.cpp #qt creator does not handle this well #SOURCES += $$files(../../libi2pd/*.cpp) @@ -166,7 +167,8 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../daemon/Daemon.h \ ../../daemon/HTTPServer.h \ ../../daemon/I2PControl.h \ - ../../daemon/UPnP.h + ../../daemon/UPnP.h \ + textbrowsertweaked1.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 840f5b5b..3a947bd1 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,6 +1,8 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" +#include "ui_statushtmlpaneform.h" +#include #include #include #include @@ -10,6 +12,8 @@ #include "FS.h" #include "Log.h" +#include "HTTPServer.h" + #ifndef ANDROID # include #endif @@ -28,6 +32,8 @@ MainWindow::MainWindow(QWidget *parent) : #ifndef ANDROID ,quitting(false) #endif + ,wasSelectingAtStatusMainPage(false) + ,showHiddenInfoStatusMainPage(false) ,ui(new Ui::MainWindow) ,statusButtonsUI(new Ui::StatusButtonsForm) ,i2pController(nullptr) @@ -40,6 +46,8 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); statusButtonsUI->setupUi(ui->statusButtonsPane); + //,statusHtmlUI(new Ui::StatusHtmlPaneForm) + //statusHtmlUI->setupUi(lastStatusWidgetui->statusWidget); ui->statusButtonsPane->setFixedSize(171,300); ui->verticalLayout->setGeometry(QRect(0,0,171,ui->verticalLayout->geometry().height())); //ui->statusButtonsPane->adjustSize(); @@ -75,8 +83,17 @@ MainWindow::MainWindow(QWidget *parent) : createTrayIcon(); #endif - QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusPage())); - setStatusButtonsVisible(true); + textBrowser = new TextBrowserTweaked1(); + ui->verticalLayout_2->addWidget(textBrowser); + scheduleMainPageUpdates(); + + QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusMainPage())); + showStatusMainPage(); + QObject::connect(statusButtonsUI->mainPagePushButton, SIGNAL(released()), this, SLOT(showStatusMainPage())); + QObject::connect(textBrowser, SIGNAL(mouseReleased()), this, SLOT(statusHtmlPageMouseReleased())); + QObject::connect(textBrowser, SIGNAL(selectionChanged()), this, SLOT(statusHtmlPageSelectionChanged())); + + QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage())); QObject::connect(ui->tunnelsPagePushButton, SIGNAL(released()), this, SLOT(showTunnelsPage())); @@ -243,6 +260,49 @@ void MainWindow::setStatusButtonsVisible(bool visible) { ui->statusButtonsPane->setVisible(visible); } +// see also: HTTPServer.cpp +QString MainWindow::getStatusMainPageHtml(bool showHiddenInfo) { + std::stringstream s; + + i2p::http::ShowStatus (s, showHiddenInfo); + + std::string str = s.str(); + return QString::fromStdString(str); +} + +void MainWindow::showStatusMainPage() { + showHiddenInfoStatusMainPage=false; + showStatusPage(); + textBrowser->setHtml(getStatusMainPageHtml(false)); + textBrowser->show(); + wasSelectingAtStatusMainPage=false; +} + +void MainWindow::scheduleMainPageUpdates() { + statusMainPageUpdateTimer = new QTimer(this); + connect(statusMainPageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateStatusMainPage())); + statusMainPageUpdateTimer->start(10*1000/*millis*/); +} + +void MainWindow::statusHtmlPageMouseReleased() { + if(wasSelectingAtStatusMainPage){ + QString selection = textBrowser->textCursor().selectedText(); + if(!selection.isEmpty()&&!selection.isNull())return; + } + showHiddenInfoStatusMainPage=!showHiddenInfoStatusMainPage; + textBrowser->setHtml(getStatusMainPageHtml(showHiddenInfoStatusMainPage)); +} + +void MainWindow::statusHtmlPageSelectionChanged() { + wasSelectingAtStatusMainPage=true; +} + +void MainWindow::updateStatusMainPage() { + showHiddenInfoStatusMainPage=false; + textBrowser->setHtml(getStatusMainPageHtml(showHiddenInfoStatusMainPage)); +} + + //TODO void MainWindow::resizeEvent(QResizeEvent *event) { @@ -363,6 +423,7 @@ void MainWindow::handleGracefulQuitTimerEvent() { MainWindow::~MainWindow() { qDebug("Destroying main window"); + delete statusMainPageUpdateTimer; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->deleteLater(); @@ -642,3 +703,4 @@ void MainWindow::addClientTunnelPushButtonReleased() { void MainWindow::setI2PController(i2p::qt::Controller* controller_) { this->i2pController = controller_; } + diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index fbadf83e..e973cfe1 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -40,6 +40,7 @@ #include "ServerTunnelPane.h" #include "ClientTunnelPane.h" #include "TunnelConfig.h" +#include "textbrowsertweaked1.h" #include "Config.h" #include "FS.h" @@ -306,8 +307,9 @@ public: }; namespace Ui { -class MainWindow; -class StatusButtonsForm; + class MainWindow; + class StatusButtonsForm; + class StatusHtmlPaneForm; } using namespace i2p::client; @@ -343,13 +345,23 @@ private slots: void iconActivated(QSystemTrayIcon::ActivationReason reason); void toggleVisibilitySlot(); #endif - void showStatusPage(); + void showStatusMainPage(); + void statusHtmlPageMouseReleased(); + void statusHtmlPageSelectionChanged(); + void updateStatusMainPage(); + void scheduleMainPageUpdates(); + void showSettingsPage(); void showTunnelsPage(); void showRestartPage(); void showQuitPage(); private: + QTimer * statusMainPageUpdateTimer; + bool wasSelectingAtStatusMainPage; + bool showHiddenInfoStatusMainPage; + + void showStatusPage(); #ifndef ANDROID void createActions(); void createTrayIcon(); @@ -362,6 +374,8 @@ private: Ui::MainWindow* ui; Ui::StatusButtonsForm* statusButtonsUI; + TextBrowserTweaked1 * textBrowser; + i2p::qt::Controller* i2pController; protected: @@ -373,6 +387,8 @@ protected: void setStatusButtonsVisible(bool visible); + QString getStatusMainPageHtml(bool showHiddenInfo); + QList configItems; NonGUIOptionItem* logOption; NonGUIOptionItem* daemonOption; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 60aacbe2..59033e9d 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -6,19 +6,19 @@ 0 0 - 904 + 908 550 - 904 + 908 0 - 950 + 908 16777215 @@ -34,13 +34,13 @@ - 904 - 0 + 908 + 550 - 16777215 + 908 550 @@ -49,8 +49,8 @@ 10 10 - 931 - 715 + 888 + 530 @@ -183,26 +183,32 @@ - 16777215 + 713 713 - 2 + 0 + + + 0 + 0 + + 0 0 - 686 + 713 531 - QLayout::SetMinAndMaxSize + QLayout::SetMaximumSize @@ -217,17 +223,11 @@ - - - Qt::Vertical + + + QLayout::SetMaximumSize - - - 20 - 40 - - - +
@@ -244,7 +244,7 @@ 0 0 - 706 + 711 531 @@ -283,8 +283,8 @@ 0 0 - 684 - 496 + 80 + 26 @@ -3045,7 +3045,7 @@ Comma separated list of base64 identities: 0 0 - 706 + 711 531 @@ -3110,7 +3110,7 @@ Comma separated list of base64 identities: - -18 + 0 0 699 425 @@ -3128,8 +3128,8 @@ Comma separated list of base64 identities: 0 0 - 686 - 496 + 711 + 531 @@ -3183,8 +3183,8 @@ Comma separated list of base64 identities: 0 0 - 686 - 496 + 711 + 531 diff --git a/qt/i2pd_qt/textbrowsertweaked1.cpp b/qt/i2pd_qt/textbrowsertweaked1.cpp new file mode 100644 index 00000000..7d0f5132 --- /dev/null +++ b/qt/i2pd_qt/textbrowsertweaked1.cpp @@ -0,0 +1,6 @@ +#include "textbrowsertweaked1.h" + +TextBrowserTweaked1::TextBrowserTweaked1() +{ + +} diff --git a/qt/i2pd_qt/textbrowsertweaked1.h b/qt/i2pd_qt/textbrowsertweaked1.h new file mode 100644 index 00000000..d64c58d8 --- /dev/null +++ b/qt/i2pd_qt/textbrowsertweaked1.h @@ -0,0 +1,22 @@ +#ifndef TEXTBROWSERTWEAKED1_H +#define TEXTBROWSERTWEAKED1_H + +#include + +class TextBrowserTweaked1 : public QTextBrowser +{ + Q_OBJECT + +public: + TextBrowserTweaked1(); + +signals: + void mouseReleased(); + +protected: + void mouseReleaseEvent(QMouseEvent *event) { + emit mouseReleased(); + } +}; + +#endif // TEXTBROWSERTWEAKED1_H From 856dda68dbcd6eb706ee319113c2b72dc985c9ef Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 2 Aug 2017 04:12:37 +0800 Subject: [PATCH 06/81] qt ui - now all buttons have handlers --- daemon/HTTPServer.cpp | 16 ++++----- daemon/HTTPServer.h | 9 +++++ qt/i2pd_qt/mainwindow.cpp | 69 ++++++++++++++++++++++++++++----------- qt/i2pd_qt/mainwindow.h | 27 +++++++++++---- 4 files changed, 88 insertions(+), 33 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 1f7dbc7b..82939bbf 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -273,7 +273,7 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } - static void ShowLocalDestinations (std::stringstream& s) + void ShowLocalDestinations (std::stringstream& s) { s << "Local Destinations:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetDestinations ()) @@ -399,7 +399,7 @@ namespace http { ShowError(s, "I2CP is not enabled"); } - static void ShowLeasesSets(std::stringstream& s) + void ShowLeasesSets(std::stringstream& s) { s << "
LeaseSets (click on to show info):

\r\n"; int counter = 1; @@ -432,7 +432,7 @@ namespace http { // end for each lease set } - static void ShowTunnels (std::stringstream& s) + void ShowTunnels (std::stringstream& s) { s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; @@ -454,7 +454,7 @@ namespace http { s << "
\r\n"; } - static void ShowCommands (std::stringstream& s, uint32_t token) + void ShowCommands (std::stringstream& s, uint32_t token) { /* commands */ s << "Router Commands
\r\n"; @@ -476,7 +476,7 @@ namespace http { s << " Force shutdown
\r\n"; } - static void ShowTransitTunnels (std::stringstream& s) + void ShowTransitTunnels (std::stringstream& s) { s << "Transit tunnels:
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) @@ -491,7 +491,7 @@ namespace http { } } - static void ShowTransports (std::stringstream& s) + void ShowTransports (std::stringstream& s) { s << "Transports:
\r\n
\r\n"; auto ntcpServer = i2p::transport::transports.GetNTCPServer (); @@ -577,7 +577,7 @@ namespace http { } } - static void ShowSAMSessions (std::stringstream& s) + void ShowSAMSessions (std::stringstream& s) { auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { @@ -624,7 +624,7 @@ namespace http { } } - static void ShowI2PTunnels (std::stringstream& s) + void ShowI2PTunnels (std::stringstream& s) { s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index edff1bf3..79f265b8 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -77,7 +77,16 @@ namespace http boost::asio::ip::tcp::acceptor m_Acceptor; }; + //all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml void ShowStatus (std::stringstream& s, bool includeHiddenContent); + void ShowLocalDestinations (std::stringstream& s); + void ShowLeasesSets(std::stringstream& s); + void ShowTunnels (std::stringstream& s); + void ShowCommands (std::stringstream& s, uint32_t token); + void ShowTransitTunnels (std::stringstream& s); + void ShowTransports (std::stringstream& s); + void ShowSAMSessions (std::stringstream& s); + void ShowI2PTunnels (std::stringstream& s); } // http } // i2p diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 3a947bd1..b465bc18 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,3 +1,4 @@ +#include #include "mainwindow.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" @@ -85,11 +86,20 @@ MainWindow::MainWindow(QWidget *parent) : textBrowser = new TextBrowserTweaked1(); ui->verticalLayout_2->addWidget(textBrowser); - scheduleMainPageUpdates(); + scheduleStatusPageUpdates(); QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusMainPage())); showStatusMainPage(); QObject::connect(statusButtonsUI->mainPagePushButton, SIGNAL(released()), this, SLOT(showStatusMainPage())); + QObject::connect(statusButtonsUI->routerCommandsPushButton, SIGNAL(released()), this, SLOT(showStatus_commands_Page())); + QObject::connect(statusButtonsUI->localDestinationsPushButton, SIGNAL(released()), this, SLOT(showStatus_local_destinations_Page())); + QObject::connect(statusButtonsUI->leasesetsPushButton, SIGNAL(released()), this, SLOT(showStatus_leasesets_Page())); + QObject::connect(statusButtonsUI->tunnelsPushButton, SIGNAL(released()), this, SLOT(showStatus_tunnels_Page())); + QObject::connect(statusButtonsUI->transitTunnelsPushButton, SIGNAL(released()), this, SLOT(showStatus_transit_tunnels_Page())); + QObject::connect(statusButtonsUI->transportsPushButton, SIGNAL(released()), this, SLOT(showStatus_transports_Page())); + QObject::connect(statusButtonsUI->i2pTunnelsPushButton, SIGNAL(released()), this, SLOT(showStatus_i2p_tunnels_Page())); + QObject::connect(statusButtonsUI->samSessionsPushButton, SIGNAL(released()), this, SLOT(showStatus_sam_sessions_Page())); + QObject::connect(textBrowser, SIGNAL(mouseReleased()), this, SLOT(statusHtmlPageMouseReleased())); QObject::connect(textBrowser, SIGNAL(selectionChanged()), this, SLOT(statusHtmlPageSelectionChanged())); @@ -250,7 +260,14 @@ MainWindow::MainWindow(QWidget *parent) : //QMetaObject::connectSlotsByName(this); } -void MainWindow::showStatusPage(){ui->stackedWidget->setCurrentIndex(0);setStatusButtonsVisible(true);} +void MainWindow::showStatusPage(StatusPage newStatusPage){ + ui->stackedWidget->setCurrentIndex(0); + setStatusButtonsVisible(true); + statusPage=newStatusPage; + showHiddenInfoStatusMainPage=false; + textBrowser->setHtml(getStatusPageHtml(false)); + wasSelectingAtStatusMainPage=false; +} void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(1);setStatusButtonsVisible(false);} void MainWindow::showTunnelsPage(){ui->stackedWidget->setCurrentIndex(2);setStatusButtonsVisible(false);} void MainWindow::showRestartPage(){ui->stackedWidget->setCurrentIndex(3);setStatusButtonsVisible(false);} @@ -261,27 +278,41 @@ void MainWindow::setStatusButtonsVisible(bool visible) { } // see also: HTTPServer.cpp -QString MainWindow::getStatusMainPageHtml(bool showHiddenInfo) { +QString MainWindow::getStatusPageHtml(bool showHiddenInfo) { std::stringstream s; - i2p::http::ShowStatus (s, showHiddenInfo); + switch (statusPage) { + case main_page: i2p::http::ShowStatus(s, showHiddenInfo);break; + case commands: i2p::http::ShowCommands(s, /*token=*/0); break; + case local_destinations: i2p::http::ShowLocalDestinations(s);break; + case leasesets: i2p::http::ShowLeasesSets(s); break; + case tunnels: i2p::http::ShowTunnels(s); break; + case transit_tunnels: i2p::http::ShowTransitTunnels(s); break; + case transports: i2p::http::ShowTransports(s); break; + case i2p_tunnels: i2p::http::ShowI2PTunnels(s); break; + case sam_sessions: i2p::http::ShowSAMSessions(s); break; + default: assert(false); break; + } std::string str = s.str(); return QString::fromStdString(str); } -void MainWindow::showStatusMainPage() { - showHiddenInfoStatusMainPage=false; - showStatusPage(); - textBrowser->setHtml(getStatusMainPageHtml(false)); - textBrowser->show(); - wasSelectingAtStatusMainPage=false; -} +void MainWindow::showStatusMainPage() { showStatusPage(StatusPage::main_page); } +void MainWindow::showStatus_commands_Page() { showStatusPage(StatusPage::commands); } +void MainWindow::showStatus_local_destinations_Page() { showStatusPage(StatusPage::local_destinations); } +void MainWindow::showStatus_leasesets_Page() { showStatusPage(StatusPage::leasesets); } +void MainWindow::showStatus_tunnels_Page() { showStatusPage(StatusPage::tunnels); } +void MainWindow::showStatus_transit_tunnels_Page() { showStatusPage(StatusPage::transit_tunnels); } +void MainWindow::showStatus_transports_Page() { showStatusPage(StatusPage::transports); } +void MainWindow::showStatus_i2p_tunnels_Page() { showStatusPage(StatusPage::i2p_tunnels); } +void MainWindow::showStatus_sam_sessions_Page() { showStatusPage(StatusPage::sam_sessions); } -void MainWindow::scheduleMainPageUpdates() { - statusMainPageUpdateTimer = new QTimer(this); - connect(statusMainPageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateStatusMainPage())); - statusMainPageUpdateTimer->start(10*1000/*millis*/); + +void MainWindow::scheduleStatusPageUpdates() { + statusPageUpdateTimer = new QTimer(this); + connect(statusPageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateStatusPage())); + statusPageUpdateTimer->start(10*1000/*millis*/); } void MainWindow::statusHtmlPageMouseReleased() { @@ -290,16 +321,16 @@ void MainWindow::statusHtmlPageMouseReleased() { if(!selection.isEmpty()&&!selection.isNull())return; } showHiddenInfoStatusMainPage=!showHiddenInfoStatusMainPage; - textBrowser->setHtml(getStatusMainPageHtml(showHiddenInfoStatusMainPage)); + textBrowser->setHtml(getStatusPageHtml(showHiddenInfoStatusMainPage)); } void MainWindow::statusHtmlPageSelectionChanged() { wasSelectingAtStatusMainPage=true; } -void MainWindow::updateStatusMainPage() { +void MainWindow::updateStatusPage() { showHiddenInfoStatusMainPage=false; - textBrowser->setHtml(getStatusMainPageHtml(showHiddenInfoStatusMainPage)); + textBrowser->setHtml(getStatusPageHtml(showHiddenInfoStatusMainPage)); } @@ -423,7 +454,7 @@ void MainWindow::handleGracefulQuitTimerEvent() { MainWindow::~MainWindow() { qDebug("Destroying main window"); - delete statusMainPageUpdateTimer; + delete statusPageUpdateTimer; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->deleteLater(); diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index e973cfe1..1c538810 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -335,7 +335,12 @@ public: // void setVisible(bool visible); //#endif +private: + + enum StatusPage {main_page, commands, local_destinations, leasesets, tunnels, transit_tunnels, + transports, i2p_tunnels, sam_sessions}; private slots: + void handleQuitButton(); void handleGracefulQuitButton(); void handleDoRestartButton(); @@ -345,11 +350,20 @@ private slots: void iconActivated(QSystemTrayIcon::ActivationReason reason); void toggleVisibilitySlot(); #endif - void showStatusMainPage(); + void scheduleStatusPageUpdates(); void statusHtmlPageMouseReleased(); void statusHtmlPageSelectionChanged(); - void updateStatusMainPage(); - void scheduleMainPageUpdates(); + void updateStatusPage(); + + void showStatusMainPage(); + void showStatus_commands_Page(); + void showStatus_local_destinations_Page(); + void showStatus_leasesets_Page(); + void showStatus_tunnels_Page(); + void showStatus_transit_tunnels_Page(); + void showStatus_transports_Page(); + void showStatus_i2p_tunnels_Page(); + void showStatus_sam_sessions_Page(); void showSettingsPage(); void showTunnelsPage(); @@ -357,11 +371,12 @@ private slots: void showQuitPage(); private: - QTimer * statusMainPageUpdateTimer; + StatusPage statusPage; + QTimer * statusPageUpdateTimer; bool wasSelectingAtStatusMainPage; bool showHiddenInfoStatusMainPage; - void showStatusPage(); + void showStatusPage(StatusPage newStatusPage); #ifndef ANDROID void createActions(); void createTrayIcon(); @@ -387,7 +402,7 @@ protected: void setStatusButtonsVisible(bool visible); - QString getStatusMainPageHtml(bool showHiddenInfo); + QString getStatusPageHtml(bool showHiddenInfo); QList configItems; NonGUIOptionItem* logOption; From db0e02c05df9d9b61fd63d0fe2840d7b8347f6c3 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Wed, 2 Aug 2017 05:05:56 +0800 Subject: [PATCH 07/81] qt ui - status commands are now pushbuttons with no handlers --- daemon/HTTPServer.cpp | 2 +- daemon/HTTPServer.h | 1 - qt/i2pd_qt/i2pd_qt.pro | 3 +- qt/i2pd_qt/mainwindow.cpp | 32 +++++++--- qt/i2pd_qt/mainwindow.h | 7 ++- qt/i2pd_qt/mainwindow.ui | 4 +- qt/i2pd_qt/routercommandswidget.ui | 94 ++++++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 qt/i2pd_qt/routercommandswidget.ui diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 82939bbf..a019acaf 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -454,7 +454,7 @@ namespace http { s << "
\r\n"; } - void ShowCommands (std::stringstream& s, uint32_t token) + static void ShowCommands (std::stringstream& s, uint32_t token) { /* commands */ s << "Router Commands
\r\n"; diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index 79f265b8..b65c9094 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -82,7 +82,6 @@ namespace http void ShowLocalDestinations (std::stringstream& s); void ShowLeasesSets(std::stringstream& s); void ShowTunnels (std::stringstream& s); - void ShowCommands (std::stringstream& s, uint32_t token); void ShowTransitTunnels (std::stringstream& s); void ShowTransports (std::stringstream& s); void ShowSAMSessions (std::stringstream& s); diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 918f0230..c1ce8c5c 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -177,7 +177,8 @@ INCLUDEPATH += . FORMS += mainwindow.ui \ tunnelform.ui \ - statusbuttons.ui + statusbuttons.ui \ + routercommandswidget.ui LIBS += -lz diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index b465bc18..b342efe1 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,9 +1,11 @@ +#include #include #include "mainwindow.h" #include "ui_mainwindow.h" #include "ui_statusbuttons.h" -#include "ui_statushtmlpaneform.h" +#include "ui_routercommandswidget.h" #include +#include #include #include #include @@ -12,6 +14,7 @@ #include "Config.h" #include "FS.h" #include "Log.h" +#include "RouterContext.h" #include "HTTPServer.h" @@ -19,10 +22,6 @@ # include #endif -#include - -#include - #include "DaemonQT.h" #include "SignatureTypeComboboxFactory.h" @@ -37,6 +36,8 @@ MainWindow::MainWindow(QWidget *parent) : ,showHiddenInfoStatusMainPage(false) ,ui(new Ui::MainWindow) ,statusButtonsUI(new Ui::StatusButtonsForm) + ,routerCommandsUI(new Ui::routerCommandsWidget) + ,routerCommandsParent(new QWidget(this)) ,i2pController(nullptr) ,configItems() ,datadir() @@ -47,6 +48,9 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); statusButtonsUI->setupUi(ui->statusButtonsPane); + routerCommandsUI->setupUi(routerCommandsParent); + routerCommandsParent->hide(); + ui->verticalLayout_2->addWidget(routerCommandsParent); //,statusHtmlUI(new Ui::StatusHtmlPaneForm) //statusHtmlUI->setupUi(lastStatusWidgetui->statusWidget); ui->statusButtonsPane->setFixedSize(171,300); @@ -260,12 +264,26 @@ MainWindow::MainWindow(QWidget *parent) : //QMetaObject::connectSlotsByName(this); } +void MainWindow::updateRouterCommandsButtons() { + bool acceptsTunnels = i2p::context.AcceptsTunnels (); + routerCommandsUI->declineTransitTunnelsPushButton->setEnabled(acceptsTunnels); + routerCommandsUI->acceptTransitTunnelsPushButton->setEnabled(!acceptsTunnels); +} + void MainWindow::showStatusPage(StatusPage newStatusPage){ ui->stackedWidget->setCurrentIndex(0); setStatusButtonsVisible(true); statusPage=newStatusPage; showHiddenInfoStatusMainPage=false; - textBrowser->setHtml(getStatusPageHtml(false)); + if(newStatusPage!=StatusPage::commands){ + textBrowser->setHtml(getStatusPageHtml(false)); + textBrowser->show(); + routerCommandsParent->hide(); + }else{ + routerCommandsParent->show(); + textBrowser->hide(); + updateRouterCommandsButtons(); + } wasSelectingAtStatusMainPage=false; } void MainWindow::showSettingsPage(){ui->stackedWidget->setCurrentIndex(1);setStatusButtonsVisible(false);} @@ -283,7 +301,7 @@ QString MainWindow::getStatusPageHtml(bool showHiddenInfo) { switch (statusPage) { case main_page: i2p::http::ShowStatus(s, showHiddenInfo);break; - case commands: i2p::http::ShowCommands(s, /*token=*/0); break; + case commands: break; case local_destinations: i2p::http::ShowLocalDestinations(s);break; case leasesets: i2p::http::ShowLeasesSets(s); break; case tunnels: i2p::http::ShowTunnels(s); break; diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 1c538810..2a1e7d64 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -309,7 +309,7 @@ public: namespace Ui { class MainWindow; class StatusButtonsForm; - class StatusHtmlPaneForm; + class routerCommandsWidget; } using namespace i2p::client; @@ -388,12 +388,17 @@ private: Ui::MainWindow* ui; Ui::StatusButtonsForm* statusButtonsUI; + Ui::routerCommandsWidget* routerCommandsUI; TextBrowserTweaked1 * textBrowser; + QWidget * routerCommandsParent; i2p::qt::Controller* i2pController; protected: + + void updateRouterCommandsButtons(); + #ifndef ANDROID void closeEvent(QCloseEvent *event); #endif diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 59033e9d..6945a2a2 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -283,8 +283,8 @@ 0 0 - 80 - 26 + 689 + 496 diff --git a/qt/i2pd_qt/routercommandswidget.ui b/qt/i2pd_qt/routercommandswidget.ui new file mode 100644 index 00000000..fa4f2177 --- /dev/null +++ b/qt/i2pd_qt/routercommandswidget.ui @@ -0,0 +1,94 @@ + + + routerCommandsWidget + + + + 0 + 0 + 400 + 300 + + + + + 0 + 0 + + + + Form + + + + + 0 + 0 + 401 + 301 + + + + + + + + 75 + true + + + + Router Commands + + + + + + + Run peer test + + + + + + + Decline transit tunnels + + + + + + + Accept transit tunnels + + + + + + + false + + + Cancel graceful quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + From 822995cbaf5e44359bdb88e7f315e40581644754 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Thu, 3 Aug 2017 06:18:21 +0800 Subject: [PATCH 08/81] ignored android/libs/ --- .gitignore | 2 ++ qt/i2pd_qt/pagewithbackbutton.cpp | 6 ++++++ qt/i2pd_qt/pagewithbackbutton.h | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 qt/i2pd_qt/pagewithbackbutton.cpp create mode 100644 qt/i2pd_qt/pagewithbackbutton.h diff --git a/.gitignore b/.gitignore index 5424262f..353d839f 100644 --- a/.gitignore +++ b/.gitignore @@ -262,3 +262,5 @@ qt/i2pd_qt/*.ui.autosave qt/i2pd_qt/*.ui.bk* qt/i2pd_qt/*.ui_* +#unknown android stuff +android/libs/ diff --git a/qt/i2pd_qt/pagewithbackbutton.cpp b/qt/i2pd_qt/pagewithbackbutton.cpp new file mode 100644 index 00000000..c1692552 --- /dev/null +++ b/qt/i2pd_qt/pagewithbackbutton.cpp @@ -0,0 +1,6 @@ +#include "pagewithbackbutton.h" + +PageWithBackButton::PageWithBackButton(QWidget *parent) : QWidget(parent) +{ + +} diff --git a/qt/i2pd_qt/pagewithbackbutton.h b/qt/i2pd_qt/pagewithbackbutton.h new file mode 100644 index 00000000..eef97b26 --- /dev/null +++ b/qt/i2pd_qt/pagewithbackbutton.h @@ -0,0 +1,17 @@ +#ifndef PAGEWITHBACKBUTTON_H +#define PAGEWITHBACKBUTTON_H + +#include + +class PageWithBackButton : public QWidget +{ + Q_OBJECT +public: + explicit PageWithBackButton(QWidget *parent = 0); + +signals: + +public slots: +}; + +#endif // PAGEWITHBACKBUTTON_H \ No newline at end of file From 07fe51fa25ab9afeabc45a09874d9626aaddaf3e Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 20 Aug 2017 10:22:30 +0800 Subject: [PATCH 09/81] some qt gui changes --- daemon/HTTPServer.cpp | 2 +- daemon/HTTPServer.h | 1 + qt/i2pd_qt/i2pd_qt.pro | 6 ++- qt/i2pd_qt/mainwindow.cpp | 62 +++++++++++++++++++++++++++++- qt/i2pd_qt/mainwindow.h | 11 ++++++ qt/i2pd_qt/pagewithbackbutton.cpp | 20 +++++++++- qt/i2pd_qt/pagewithbackbutton.h | 10 +++-- qt/i2pd_qt/routercommandswidget.ui | 37 +++++++++++++++++- qt/i2pd_qt/textbrowsertweaked1.cpp | 7 +++- qt/i2pd_qt/textbrowsertweaked1.h | 6 ++- 10 files changed, 148 insertions(+), 14 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index a019acaf..d491e8a0 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -341,7 +341,7 @@ namespace http { s << "
" << std::endl; } - static void ShowLocalDestination (std::stringstream& s, const std::string& b32) + void ShowLocalDestination (std::stringstream& s, const std::string& b32) { s << "Local Destination:
\r\n
\r\n"; i2p::data::IdentHash ident; diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h index b65c9094..ec718532 100644 --- a/daemon/HTTPServer.h +++ b/daemon/HTTPServer.h @@ -86,6 +86,7 @@ namespace http void ShowTransports (std::stringstream& s); void ShowSAMSessions (std::stringstream& s); void ShowI2PTunnels (std::stringstream& s); + void ShowLocalDestination (std::stringstream& s, const std::string& b32); } // http } // i2p diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index c1ce8c5c..06760bb7 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -88,7 +88,8 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../daemon/I2PControl.cpp \ ../../daemon/UnixDaemon.cpp \ ../../daemon/UPnP.cpp \ - textbrowsertweaked1.cpp + textbrowsertweaked1.cpp \ + pagewithbackbutton.cpp #qt creator does not handle this well #SOURCES += $$files(../../libi2pd/*.cpp) @@ -168,7 +169,8 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../daemon/HTTPServer.h \ ../../daemon/I2PControl.h \ ../../daemon/UPnP.h \ - textbrowsertweaked1.h + textbrowsertweaked1.h \ + pagewithbackbutton.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index b342efe1..79516206 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -15,6 +15,7 @@ #include "FS.h" #include "Log.h" #include "RouterContext.h" +#include "Transports.h" #include "HTTPServer.h" @@ -60,7 +61,7 @@ MainWindow::MainWindow(QWidget *parent) : setWindowTitle(QApplication::translate("AppTitle","I2PD")); //TODO handle resizes and change the below into resize() call - setFixedSize(width(), 550); + setFixedHeight(550); ui->centralWidget->setFixedHeight(550); onResize(); @@ -88,8 +89,21 @@ MainWindow::MainWindow(QWidget *parent) : createTrayIcon(); #endif - textBrowser = new TextBrowserTweaked1(); + textBrowser = new TextBrowserTweaked1(this); + //textBrowser->setOpenExternalLinks(false); + textBrowser->setOpenLinks(false); + /*textBrowser->setTextInteractionFlags(textBrowser->textInteractionFlags()| + Qt::LinksAccessibleByMouse|Qt::LinksAccessibleByKeyboard| + Qt::TextSelectableByMouse|Qt::TextSelectableByKeyboard);*/ ui->verticalLayout_2->addWidget(textBrowser); + childTextBrowser = new TextBrowserTweaked1(this); + //childTextBrowser->setOpenExternalLinks(false); + childTextBrowser->setOpenLinks(false); + connect(textBrowser, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(anchorClickedHandler(const QUrl&))); + pageWithBackButton = new PageWithBackButton(this, childTextBrowser); + ui->verticalLayout_2->addWidget(pageWithBackButton); + pageWithBackButton->hide(); + connect(pageWithBackButton, SIGNAL(backReleased()), this, SLOT(backClickedFromChild())); scheduleStatusPageUpdates(); QObject::connect(ui->statusPagePushButton, SIGNAL(released()), this, SLOT(showStatusMainPage())); @@ -107,6 +121,9 @@ MainWindow::MainWindow(QWidget *parent) : QObject::connect(textBrowser, SIGNAL(mouseReleased()), this, SLOT(statusHtmlPageMouseReleased())); QObject::connect(textBrowser, SIGNAL(selectionChanged()), this, SLOT(statusHtmlPageSelectionChanged())); + QObject::connect(routerCommandsUI->runPeerTestPushButton, SIGNAL(released()), this, SLOT(runPeerTest())); + QObject::connect(routerCommandsUI->acceptTransitTunnelsPushButton, SIGNAL(released()), this, SLOT(enableTransit())); + QObject::connect(routerCommandsUI->declineTransitTunnelsPushButton, SIGNAL(released()), this, SLOT(disableTransit())); QObject::connect(ui->settingsPagePushButton, SIGNAL(released()), this, SLOT(showSettingsPage())); @@ -279,9 +296,11 @@ void MainWindow::showStatusPage(StatusPage newStatusPage){ textBrowser->setHtml(getStatusPageHtml(false)); textBrowser->show(); routerCommandsParent->hide(); + pageWithBackButton->hide(); }else{ routerCommandsParent->show(); textBrowser->hide(); + pageWithBackButton->hide(); updateRouterCommandsButtons(); } wasSelectingAtStatusMainPage=false; @@ -299,6 +318,8 @@ void MainWindow::setStatusButtonsVisible(bool visible) { QString MainWindow::getStatusPageHtml(bool showHiddenInfo) { std::stringstream s; + s << ""; + switch (statusPage) { case main_page: i2p::http::ShowStatus(s, showHiddenInfo);break; case commands: break; @@ -753,3 +774,40 @@ void MainWindow::setI2PController(i2p::qt::Controller* controller_) { this->i2pController = controller_; } +void MainWindow::runPeerTest() { + i2p::transport::transports.PeerTest(); +} + +void MainWindow::enableTransit() { + i2p::context.SetAcceptsTunnels(true); + updateRouterCommandsButtons(); +} + +void MainWindow::disableTransit() { + i2p::context.SetAcceptsTunnels(false); + updateRouterCommandsButtons(); +} + +void MainWindow::anchorClickedHandler(const QUrl & link) { + QString debugStr=QString()+"anchorClicked: "+"\""+link.toString()+"\""; + qDebug()<show(); + textBrowser->hide(); + std::stringstream s; + i2p::http::ShowLocalDestination(s,str.toStdString()); + childTextBrowser->setHtml(QString::fromStdString(s.str())); + } +} + +void MainWindow::backClickedFromChild() { + showStatusPage(statusPage); +} diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 2a1e7d64..829cac37 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -24,6 +24,7 @@ #include #include #include "QVBoxLayout" +#include "QUrl" #ifndef ANDROID # include @@ -54,6 +55,7 @@ #include "DaemonQT.h" #include "SignatureTypeComboboxFactory.h" +#include "pagewithbackbutton.h" template bool isType(boost::any& a) { @@ -357,6 +359,10 @@ private slots: void showStatusMainPage(); void showStatus_commands_Page(); + void runPeerTest(); + void enableTransit(); + void disableTransit(); + void showStatus_local_destinations_Page(); void showStatus_leasesets_Page(); void showStatus_tunnels_Page(); @@ -392,6 +398,8 @@ private: TextBrowserTweaked1 * textBrowser; QWidget * routerCommandsParent; + PageWithBackButton * pageWithBackButton; + TextBrowserTweaked1 * childTextBrowser; i2p::qt::Controller* i2pController; @@ -442,6 +450,9 @@ public slots: void addServerTunnelPushButtonReleased(); void addClientTunnelPushButtonReleased(); + void anchorClickedHandler(const QUrl & link); + void backClickedFromChild(); + private: QString datadir; QString confpath; diff --git a/qt/i2pd_qt/pagewithbackbutton.cpp b/qt/i2pd_qt/pagewithbackbutton.cpp index c1692552..bc297ac2 100644 --- a/qt/i2pd_qt/pagewithbackbutton.cpp +++ b/qt/i2pd_qt/pagewithbackbutton.cpp @@ -1,6 +1,24 @@ #include "pagewithbackbutton.h" +#include "QVBoxLayout" +#include "QHBoxLayout" +#include "QPushButton" -PageWithBackButton::PageWithBackButton(QWidget *parent) : QWidget(parent) +PageWithBackButton::PageWithBackButton(QWidget *parent, QWidget* child) : QWidget(parent) { + QVBoxLayout * layout = new QVBoxLayout(); + setLayout(layout); + QWidget * topBar = new QWidget(); + QHBoxLayout * topBarLayout = new QHBoxLayout(); + topBar->setLayout(topBarLayout); + layout->addWidget(topBar); + layout->addWidget(child); + QPushButton * backButton = new QPushButton(topBar); + backButton->setText("< Back"); + topBarLayout->addWidget(backButton); + connect(backButton, SIGNAL(released()), this, SLOT(backReleasedSlot())); +} + +void PageWithBackButton::backReleasedSlot() { + emit backReleased(); } diff --git a/qt/i2pd_qt/pagewithbackbutton.h b/qt/i2pd_qt/pagewithbackbutton.h index eef97b26..60779f80 100644 --- a/qt/i2pd_qt/pagewithbackbutton.h +++ b/qt/i2pd_qt/pagewithbackbutton.h @@ -7,11 +7,15 @@ class PageWithBackButton : public QWidget { Q_OBJECT public: - explicit PageWithBackButton(QWidget *parent = 0); + explicit PageWithBackButton(QWidget *parent, QWidget* child); signals: -public slots: + void backReleased(); + +private slots: + + void backReleasedSlot(); }; -#endif // PAGEWITHBACKBUTTON_H \ No newline at end of file +#endif // PAGEWITHBACKBUTTON_H diff --git a/qt/i2pd_qt/routercommandswidget.ui b/qt/i2pd_qt/routercommandswidget.ui index fa4f2177..c5098e8e 100644 --- a/qt/i2pd_qt/routercommandswidget.ui +++ b/qt/i2pd_qt/routercommandswidget.ui @@ -6,7 +6,7 @@ 0 0 - 400 + 711 300
@@ -24,13 +24,22 @@ 0 0 - 401 + 711 301 + + QLayout::SetMaximumSize + + + + 0 + 0 + + 75 @@ -44,6 +53,12 @@ + + + 0 + 0 + + Run peer test @@ -51,6 +66,12 @@ + + + 0 + 0 + + Decline transit tunnels @@ -58,6 +79,12 @@ + + + 0 + 0 + + Accept transit tunnels @@ -68,6 +95,12 @@ false + + + 0 + 0 + + Cancel graceful quit diff --git a/qt/i2pd_qt/textbrowsertweaked1.cpp b/qt/i2pd_qt/textbrowsertweaked1.cpp index 7d0f5132..f8802061 100644 --- a/qt/i2pd_qt/textbrowsertweaked1.cpp +++ b/qt/i2pd_qt/textbrowsertweaked1.cpp @@ -1,6 +1,9 @@ #include "textbrowsertweaked1.h" -TextBrowserTweaked1::TextBrowserTweaked1() +TextBrowserTweaked1::TextBrowserTweaked1(QWidget * parent): QTextBrowser(parent) { - } + +/*void TextBrowserTweaked1::setSource(const QUrl & url) { + emit navigatedTo(url); +}*/ diff --git a/qt/i2pd_qt/textbrowsertweaked1.h b/qt/i2pd_qt/textbrowsertweaked1.h index d64c58d8..288a3c32 100644 --- a/qt/i2pd_qt/textbrowsertweaked1.h +++ b/qt/i2pd_qt/textbrowsertweaked1.h @@ -2,19 +2,23 @@ #define TEXTBROWSERTWEAKED1_H #include +#include class TextBrowserTweaked1 : public QTextBrowser { Q_OBJECT public: - TextBrowserTweaked1(); + TextBrowserTweaked1(QWidget * parent); + //virtual void setSource(const QUrl & url); signals: void mouseReleased(); + //void navigatedTo(const QUrl & link); protected: void mouseReleaseEvent(QMouseEvent *event) { + QTextBrowser::mouseReleaseEvent(event); emit mouseReleased(); } }; From f6ced9279bb7dc6dfd1552ad26b9986aa0e9f6ca Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 20 Aug 2017 17:34:53 -0400 Subject: [PATCH 10/81] new reseed added --- .../certificates/reseed/igor_at_novg.net.crt | 33 +++++++++++++++++++ libi2pd/Config.cpp | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 contrib/certificates/reseed/igor_at_novg.net.crt diff --git a/contrib/certificates/reseed/igor_at_novg.net.crt b/contrib/certificates/reseed/igor_at_novg.net.crt new file mode 100644 index 00000000..12ce7a61 --- /dev/null +++ b/contrib/certificates/reseed/igor_at_novg.net.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFvjCCA6agAwIBAgIQIDtv8tGMh0FyB2w5XjfZxTANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYDVQQK +ExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEWMBQGA1UEAwwN +aWdvckBub3ZnLm5ldDAeFw0xNzA3MjQxODI4NThaFw0yNzA3MjQxODI4NThaMG0x +CzAJBgNVBAYTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UECRMCWFgxHjAcBgNVBAoT +FUkyUCBBbm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRYwFAYDVQQDDA1p +Z29yQG5vdmcubmV0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxst4 +cam3YibBtQHGPCPX13uRQti56U3XZytSZntaKrUFmJxjt41Q/mOy3KYo+lBvhfDF +x3tWKjgP9LJOJ28zvddFhZVNxqZRjcnAoPuSOVCw88g01D9OAasKF11hCfdxZP6h +vGm8WCnjD8KPcYFxJC4HJUiFeProAwuTzEAESTRk4CAQe3Ie91JspuqoLUc5Qxlm +w5QpjnjfZY4kaVHmZDKGIZDgNIt5v85bu4pWwZ6O+o90xQqjxvjyz/xccIec3sHw +MHJ8h8ZKMokCKEJTaRWBvdeNXki7nf3gUy/3GjYQlzo0Nxk/Hw4svPcA+eL0AYiy +Jn83bIB5VToW2zYUdV4u3qHeAhEg8Y7HI0kKcSUGm9AQXzbzP8YCHxi0sbb0GAJy +f1Xf3XzoPfT64giD8ReUHhwKpyMB6uvG/NfWSZAzeAO/NT7DAwXpKIVQdkVdqy8b +mvHvjf9/kWKOirA2Nygf3r79Vbg2mqbYC/b63XI9hheU689+O7qyhTEhNz+11X0d +Zax7UPrLrwOeB9TNfEnztsmrHNdv2n+KcOO2o11Wvz2nHP9g+dgwoZSD1ZEpFzWP +0sD5knKLwAL/64qLlAQ1feqW7hMr80IADcKjLSODkIDIIGm0ksXqEzTjz1JzbRDq +jUjq7EAlkw3G69rv1gHxIntllJRQidAqecyWHOMCAwEAAaNaMFgwDgYDVR0PAQH/ +BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8E +BTADAQH/MBYGA1UdDgQPBA1pZ29yQG5vdmcubmV0MA0GCSqGSIb3DQEBCwUAA4IC +AQADyPaec28qc1HQtAV5dscJr47k92RTfvan+GEgIwyQDHZQm38eyTb05xipQCdk +5ruUDFXLB5qXXFJKUbQM6IpaktmWDJqk4Zn+1nGbtFEbKgrF55pd63+NQer5QW9o +3+dGj0eZJa3HX5EBkd2r7j2LFuB6uxv3r/xiTeHaaflCnsmyDLfb7axvYhyEzHQS +AUi1bR+ln+dXewdtuojqc1+YmVGDgzWZK2T0oOz2E21CpZUDiP3wv9QfMaotLEal +zECnbhS++q889inN3GB4kIoN6WpPpeYtTV+/r7FLv9+KUOV1s2z6mxIqC5wBFhZs +0Sr1kVo8hB/EW/YYhDp99LoAOjIO6nn1h+qttfzBYr6C16j+8lGK2A12REJ4LiUQ +cQI/0zTjt2C8Ns6ueNzMLQN1Mvmlg1Z8wIB7Az7jsIbY2zFJ0M5qR5VJveTj33K4 +4WSbC/zMWOBYHTVBvGmc6JGhu5ZUTZ+mWP7QfimGu+tdhvtrybFjE9ROIE/4yFr6 +GkxEyt0UY87TeKXJ/3KygvkMwdvqGWiZhItb807iy99+cySujtbGfF2ZXYGjBXVW +dJOVRbyGQkHh6lrWHQM4ntBv4x+5QA+OAan5PBF3tcDx1vefPx+asYslbOXpzII5 +qhvoQxuRs6j5jsVFG6RdsKNeQAt87Mb2u2zK2ZakMdyD1w== +-----END CERTIFICATE----- diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 0097eb30..f8985010 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -189,7 +189,8 @@ namespace config { "https://reseed.memcpy.io/," "https://reseed.onion.im/," "https://itoopie.atomike.ninja/," - "https://i2pseed.creativecowpat.net:8443/" + "https://i2pseed.creativecowpat.net:8443/," + "https://i2p.novg.net/" ), "Reseed URLs, separated by comma") ; From 160753541688d67226dc2ae85b6f0bfd339f8286 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 24 Aug 2017 15:13:15 -0400 Subject: [PATCH 11/81] strip out Accept and From headers --- libi2pd_client/HTTPProxy.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 50a45e99..5056b737 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -200,10 +200,11 @@ namespace proxy { void HTTPReqHandler::SanitizeHTTPRequest(i2p::http::HTTPReq & req) { /* drop common headers */ - req.RemoveHeader ("Referer"); + req.RemoveHeader("Referer"); req.RemoveHeader("Via"); + req.RemoveHeader("From"); req.RemoveHeader("Forwarded"); - req.RemoveHeader("Accept-", "Accept-Encoding"); // Accept-*, but Accept-Encoding + req.RemoveHeader("Accept", "Accept-Encoding"); // Accept*, but Accept-Encoding /* drop proxy-disclosing headers */ req.RemoveHeader("X-Forwarded"); req.RemoveHeader("Proxy-"); // Proxy-* From b9f6f92badcfca9720f7ebdc10ca41cfb40a8f26 Mon Sep 17 00:00:00 2001 From: Markovskij Date: Fri, 25 Aug 2017 02:37:01 +0300 Subject: [PATCH 12/81] Web interface fix --- daemon/HTTPServer.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d491e8a0..f3f9bb74 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -652,16 +652,19 @@ namespace http { s << "SOCKS Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; - } - s << "
\r\nServer Tunnels:
\r\n
\r\n"; - for (auto& it: i2p::client::context.GetServerTunnels ()) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; - s << it.second->GetName () << " ⇒ "; - s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << ":" << it.second->GetLocalPort (); - s << "
\r\n"<< std::endl; + } + auto& serverTunnels = i2p::client::context.GetServerTunnels (); + if (!serverTunnels.empty ()) { + s << "
\r\nServer Tunnels:
\r\n
\r\n"; + for (auto& it: serverTunnels) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + s << ""; + s << it.second->GetName () << " ⇒ "; + s << i2p::client::context.GetAddressBook ().ToAddress(ident); + s << ":" << it.second->GetLocalPort (); + s << "
\r\n"<< std::endl; + } } auto& clientForwards = i2p::client::context.GetClientForwards (); if (!clientForwards.empty ()) From 028f0bdb8ddc5394322f535048060ce8dce08eac Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 25 Aug 2017 14:45:58 -0400 Subject: [PATCH 13/81] Fixed #931. don't insert null pointer into DHkeys list --- libi2pd/Transports.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b531bf71..f375296f 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -102,9 +102,14 @@ namespace transport void DHKeysPairSupplier::Return (std::shared_ptr pair) { - std::unique_lockl(m_AcquiredMutex); - if ((int)m_Queue.size () < 2*m_QueueSize) - m_Queue.push (pair); + if (pair) + { + std::unique_lockl(m_AcquiredMutex); + if ((int)m_Queue.size () < 2*m_QueueSize) + m_Queue.push (pair); + } + else + LogPrint(eLogError, "Transports: return null DHKeys"); } Transports transports; From 0f0fb266c7968e6239cfff7d24fec79864ca87d0 Mon Sep 17 00:00:00 2001 From: NeverExist Date: Sun, 27 Aug 2017 12:57:06 +0900 Subject: [PATCH 14/81] Fix deformed json result with an extra comma {"id":1,"result":{"i2p.router.net.bw.in":48,"i2p.router.net.bw.out":48,},"jsonrpc":"2.0"} You can see there is an extra comma behind the number 48. --- daemon/I2PControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 1d7023fb..3d06b97a 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -512,10 +512,10 @@ namespace client { for (auto it = params.begin (); it != params.end (); it++) { - if (it != params.begin ()) results << ","; LogPrint (eLogDebug, "I2PControl: NetworkSetting request: ", it->first); auto it1 = m_NetworkSettingHandlers.find (it->first); if (it1 != m_NetworkSettingHandlers.end ()) { + if (it != params.begin ()) results << ","; (this->*(it1->second))(it->second.data (), results); } else LogPrint (eLogError, "I2PControl: NetworkSetting unknown request: ", it->first); From 3d5fb07ca8290a9f964f4c21022aec659711dd74 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 27 Aug 2017 12:39:00 +0800 Subject: [PATCH 15/81] various small qt gui fixes --- qt/i2pd_qt/ClientTunnelPane.h | 2 +- qt/i2pd_qt/mainwindow.cpp | 36 ++++++++++++++++++++++++++--------- qt/i2pd_qt/mainwindow.h | 32 +++++++++++++++++++++++++++---- qt/i2pd_qt/mainwindow.ui | 14 ++++++++++++-- 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index 7052211a..511209e5 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -85,7 +85,7 @@ protected: ctc->setaddress(addressLineEdit->text().toStdString()); - auto dportStr=portLineEdit->text(); + auto dportStr=destinationPortLineEdit->text(); int dportInt=dportStr.toInt(&ok); if(!ok)return false; ctc->setdestinationPort(dportInt); diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 79516206..ac431672 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -143,10 +143,16 @@ MainWindow::MainWindow(QWidget *parent) : initFileChooser( OPTION("","tunconf",[](){return "";}), ui->tunnelsConfigFileLineEdit, ui->tunnelsConfigFileBrowsePushButton); initFileChooser( OPTION("","pidfile",[]{return "";}), ui->pidFileLineEdit, ui->pidFileBrowsePushButton); - logOption=initNonGUIOption( OPTION("","log",[]{return "";})); daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";})); serviceOption=initNonGUIOption( OPTION("","service",[]{return "";})); + ui->logDestinationComboBox->clear(); + ui->logDestinationComboBox->insertItems(0, QStringList() + << QApplication::translate("MainWindow", "stdout", 0) + << QApplication::translate("MainWindow", "file", 0) + ); + initLogDestinationCombobox( OPTION("","log",[]{return "";}), ui->logDestinationComboBox); + logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), ui->logFileLineEdit, ui->logFileBrowsePushButton); initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), ui->logLevelComboBox); @@ -246,6 +252,10 @@ MainWindow::MainWindow(QWidget *parent) : loadAllConfigs(); + QObject::connect(ui->logDestinationComboBox, SIGNAL(currentIndexChanged(const QString &)), + this, SLOT(logDestinationComboBoxValueChanged(const QString &))); + logDestinationComboBoxValueChanged(ui->logDestinationComboBox->currentText()); + //tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); //tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); //tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); @@ -281,6 +291,13 @@ MainWindow::MainWindow(QWidget *parent) : //QMetaObject::connectSlotsByName(this); } +void MainWindow::logDestinationComboBoxValueChanged(const QString & text) { + bool stdout = text==QString("stdout"); + ui->logFileLineEdit->setEnabled(!stdout); + ui->logFileBrowsePushButton->setEnabled(!stdout); +} + + void MainWindow::updateRouterCommandsButtons() { bool acceptsTunnels = i2p::context.AcceptsTunnels (); routerCommandsUI->declineTransitTunnelsPushButton->setEnabled(acceptsTunnels); @@ -518,6 +535,9 @@ void MainWindow::initFolderChooser(ConfigOption option, QLineEdit* folderLineEdi configItems.append(new ComboBoxItem(option, comboBox)); QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(saveAllConfigs())); }*/ +void MainWindow::initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox){ + configItems.append(new LogDestinationComboBoxItem(option, comboBox)); +} void MainWindow::initLogLevelCombobox(ConfigOption option, QComboBox* comboBox){ configItems.append(new LogLevelComboBoxItem(option, comboBox)); } @@ -572,10 +592,7 @@ void MainWindow::loadAllConfigs(){ LogPrint(eLogWarning, "Daemon: please rename i2p.conf to i2pd.conf here: ", config); } else { config = i2p::fs::DataDirPath("i2pd.conf"); - if (!i2p::fs::Exists (config)) { - // use i2pd.conf only if exists - config = ""; /* reset */ - } + /*if (!i2p::fs::Exists (config)) {}*/ } } @@ -605,8 +622,8 @@ void MainWindow::loadAllConfigs(){ /** returns false iff not valid items present and save was aborted */ bool MainWindow::saveAllConfigs(){ programOptionsWriterCurrentSection=""; - if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); - else logOption->optionValue=boost::any(std::string("stdout")); + /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); + else logOption->optionValue=boost::any(std::string("stdout"));*/ daemonOption->optionValue=boost::any(false); serviceOption->optionValue=boost::any(false); @@ -623,9 +640,10 @@ bool MainWindow::saveAllConfigs(){ using namespace std; + QString backup=confpath+"~"; if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors - QFile::rename(confpath, backup);//TODO handle errors + if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors ofstream outfile; outfile.open(confpath.toStdString());//TODO handle errors outfile << out.str().c_str(); @@ -740,7 +758,7 @@ void MainWindow::SaveTunnelsConfig() { QString backup=tunconfpath+"~"; if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors - QFile::rename(tunconfpath, backup);//TODO handle errors + if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors ofstream outfile; outfile.open(tunconfpath.toStdString());//TODO handle errors outfile << out.str().c_str(); diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 829cac37..27f1ccc2 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -57,6 +57,8 @@ #include "SignatureTypeComboboxFactory.h" #include "pagewithbackbutton.h" +#include + template bool isType(boost::any& a) { return @@ -97,7 +99,7 @@ public: std::string optName=""; if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); optName+=option.option.toStdString(); - qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; + //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]"; boost::any programOption; i2p::config::GetOptionAsAny(optName, programOption); optionValue=programOption.empty()?boost::any(std::string("")) @@ -203,6 +205,21 @@ public: virtual void saveToStringStream(std::stringstream& out)=0; virtual bool isValid() { return true; } }; +class LogDestinationComboBoxItem : public ComboBoxItem { +public: + LogDestinationComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}; + virtual ~LogDestinationComboBoxItem(){} + virtual void loadFromConfigOption(){ + MainWindowItem::loadFromConfigOption(); + const char * ld = boost::any_cast(optionValue).c_str(); + comboBox->setCurrentText(QString(ld)); + } + virtual void saveToStringStream(std::stringstream& out){ + optionValue=comboBox->currentText().toStdString(); + MainWindowItem::saveToStringStream(out); + } + virtual bool isValid() { return true; } +}; class LogLevelComboBoxItem : public ComboBoxItem { public: LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}; @@ -418,14 +435,15 @@ protected: QString getStatusPageHtml(bool showHiddenInfo); QList configItems; - NonGUIOptionItem* logOption; NonGUIOptionItem* daemonOption; NonGUIOptionItem* serviceOption; + //LogDestinationComboBoxItem* logOption; FileChooserItem* logFileNameOption; FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton); void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); //void initCombobox(ConfigOption option, QComboBox* comboBox); + void initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox); void initLogLevelCombobox(ConfigOption option, QComboBox* comboBox); void initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox); void initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated); @@ -453,6 +471,8 @@ public slots: void anchorClickedHandler(const QUrl & link); void backClickedFromChild(); + void logDestinationComboBoxValueChanged(const QString & text); + private: QString datadir; QString confpath; @@ -635,13 +655,17 @@ private: { // mandatory params std::string dest; - if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) + if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); + std::cout << "had read tunnel dest: " << dest << std::endl; + } int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); + std::cout << "had read tunnel port: " << port << std::endl; // optional params std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); - int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); + int destinationPort = section.second.get(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); + std::cout << "had read tunnel destinationPort: " << destinationPort << std::endl; i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); // I2CP std::map options; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 6945a2a2..16a0822b 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -188,7 +188,7 @@ - 0 + 1 @@ -506,6 +506,16 @@ QLayout::SetMaximumSize + + + + Destination: + + + + + + @@ -3007,7 +3017,7 @@ Comma separated list of base64 identities: - SIgnature type: + Signature type: From 7738eae4b032f1bf7b5f29b8fb1bdd18bf98c3a6 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 27 Aug 2017 16:10:09 +0800 Subject: [PATCH 16/81] general settings widget ui revolution for convenience + widget locks: fixed #927 --- qt/i2pd_qt/ClientTunnelPane.cpp | 3 + qt/i2pd_qt/ServerTunnelPane.cpp | 3 + qt/i2pd_qt/TunnelPane.cpp | 3 + qt/i2pd_qt/TunnelPane.h | 4 + qt/i2pd_qt/generalsettingswidget.ui | 2875 +++++++++++++++++++++++++++ qt/i2pd_qt/i2pd_qt.pro | 11 +- qt/i2pd_qt/mainwindow.cpp | 194 +- qt/i2pd_qt/mainwindow.h | 7 + qt/i2pd_qt/mainwindow.ui | 2750 ------------------------- qt/i2pd_qt/widgetlock.cpp | 1 + qt/i2pd_qt/widgetlock.h | 33 + qt/i2pd_qt/widgetlockregistry.cpp | 2 + qt/i2pd_qt/widgetlockregistry.h | 23 + 13 files changed, 3060 insertions(+), 2849 deletions(-) create mode 100644 qt/i2pd_qt/generalsettingswidget.ui create mode 100644 qt/i2pd_qt/widgetlock.cpp create mode 100644 qt/i2pd_qt/widgetlock.h create mode 100644 qt/i2pd_qt/widgetlockregistry.cpp create mode 100644 qt/i2pd_qt/widgetlockregistry.h diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 9fc00509..537abb1c 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -179,6 +179,9 @@ int ClientTunnelPane::appendClientTunnelForm( QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updated())); horizontalLayout_2->addWidget(sigTypeComboBox); + QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2); + horizontalLayout_2->addWidget(lockButton2); + widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2)); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); tunnelGridLayout->addLayout(horizontalLayout_2); diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index d185be28..cc024386 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -197,6 +197,9 @@ int ServerTunnelPane::appendServerTunnelForm( QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updated())); horizontalLayout_2->addWidget(sigTypeComboBox); + QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2); + horizontalLayout_2->addWidget(lockButton2); + widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2)); QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_2->addItem(horizontalSpacer); tunnelGridLayout->addLayout(horizontalLayout_2); diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 0dda5185..84e8aed0 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -65,6 +65,9 @@ void TunnelPane::setupTunnelPane( typeLabel->setObjectName(QStringLiteral("typeLabel")); horizontalLayout_->addWidget(typeLabel); horizontalLayout_->addWidget(tunnelTypeComboBox); + QPushButton * lockButton1 = new QPushButton(gridLayoutWidget_2); + horizontalLayout_->addWidget(lockButton1); + widgetlocks.add(new widgetlock(tunnelTypeComboBox, lockButton1)); this->tunnelTypeComboBox=tunnelTypeComboBox; QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_->addItem(horizontalSpacer); diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index b7744555..f306e9dc 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -14,6 +14,9 @@ #include "TunnelConfig.h" +#include +#include + class ServerTunnelPane; class ClientTunnelPane; @@ -33,6 +36,7 @@ public: protected: TunnelConfig* tunnelConfig; + widgetlockregistry widgetlocks; TunnelsPageUpdateListener* tunnelsPageUpdateListener; QVBoxLayout *tunnelGridLayout; QGroupBox *tunnelGroupBox; diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui new file mode 100644 index 00000000..6af16ecf --- /dev/null +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -0,0 +1,2875 @@ + + + GeneralSettingsContentsForm + + + + 0 + 0 + 679 + 3033 + + + + + 0 + 0 + + + + GeneralSettingsContentsForm + + + + + 0 + 0 + 679 + 3052 + + + + + QLayout::SetMinAndMaxSize + + + + + + 0 + 0 + + + + + 0 + 51 + + + + + 16777215 + 51 + + + + Configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + + 0 + 0 + + + + + 0 + 27 + + + + + 16777215 + 27 + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 51 + + + + + 16777215 + 51 + + + + Tunnels configuration file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + + 0 + 0 + + + + + 0 + 27 + + + + + 16777215 + 27 + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 51 + + + + + 16777215 + 51 + + + + Pid file: + + + + + 0 + 18 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + + 0 + 0 + + + + + 0 + 27 + + + + + 16777215 + 27 + + + + Browse… + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + SAM interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Windows-specific options + + + + + + + + 0 + 44 + + + + + 16777215 + 44 + + + + Cryptography + + + + + 0 + 20 + 661 + 22 + + + + Use ElGamal precomputed tables + + + + + + + + + 0 + 107 + + + + + 16777215 + 107 + + + + Logging + + + Qt::AlignJustify|Qt::AlignTop + + + + + -1 + 19 + 661 + 91 + + + + + QLayout::SetMinimumSize + + + + + QLayout::SetMaximumSize + + + + + Destination: + + + + + + + + + + Edit + + + + + + + Log file: + + + + + + + + + + Browse… + + + + + + + + + QLayout::SetMinimumSize + + + + + + 0 + 0 + + + + Log level: + + + + + + + + Error + + + + + Warn + + + + + Info + + + + + Debug + + + + + + + + Edit + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 68 + + + + + 16777215 + 68 + + + + UPnP + + + + + 0 + 20 + 97 + 22 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Name i2pd appears in UPnP forwardings list: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + I2CP interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + BOB interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + General options + + + + + + + + 0 + 0 + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Router external address (for incoming connections) + + + Qt::AlignJustify|Qt::AlignTop + + + + + 0 + 20 + 661 + 81 + + + + + QLayout::SetMinAndMaxSize + + + + + QLayout::SetMinAndMaxSize + + + + + Host: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMinAndMaxSize + + + + + Port (leave empty to auto-assign): + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 78 + + + + + 16777215 + 78 + + + + Addressbook settings + + + + + 0 + 20 + 661 + 31 + + + + + + + Addressbook default subscription URL for initial setup: + + + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Addressbook subscriptions URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 280 + + + + + 16777215 + 280 + + + + HTTP proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Signature type: + + + + + + + + + + Edit + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Various options + + + + + + + + 0 + 51 + + + + + 16777215 + 51 + + + + Data folder (for storage of i2pd data — RI, keys, peer profiles, …): + + + + + 0 + 20 + 661 + 31 + + + + + QLayout::SetMaximumSize + + + + + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 215 + + + + + 16777215 + 215 + + + + Router options + + + + + 0 + 20 + 661 + 188 + + + + + + + Enable communication through ipv6 + + + + + + + Router will not accept transit tunnels at startup + + + + + + + Router will be floodfill + + + + + + + + + Bandwidth limit (integer): + + + + + + + + + + KBps + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Family (name of a family router belongs to): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + QLayout::SetMaximumSize + + + + + NetID (network ID router belongs to. The main I2P ID is 2): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + 0 + 108 + + + + + 16777215 + 108 + + + + Limits + + + + + 0 + 20 + 661 + 31 + + + + + + + Maximum number of transit tunnels: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 50 + 661 + 31 + + + + + + + Maximum number of open files (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 80 + 661 + 31 + + + + + + + Maximum size of core file in Kb (0 — use system limit): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 98 + + + + + 16777215 + 98 + + + + Reseeding + + + + + 0 + 20 + 661 + 22 + + + + Request SU3 signature verification + + + + + + 0 + 40 + 661 + 31 + + + + + + + SU3 file to reseed from: + + + + + + + + + + Browse… + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Reseed URLs, separated by comma: + + + + + + + + + + + + + + + 0 + 170 + + + + + 16777215 + 170 + + + + Trust options + + + + + 0 + 20 + 661 + 21 + + + + Enable explicit trust options + + + + + + 390 + 40 + 271 + 23 + + + + + + + 0 + 40 + 391 + 42 + + + + Make direct I2P connections only to +routers in specified Family: + + + + + + 0 + 82 + 661 + 42 + + + + Make direct I2P connections only to routers specified here. +Comma separated list of base64 identities: + + + + + + 0 + 124 + 661 + 23 + + + + + + + 0 + 147 + 661 + 21 + + + + Should we hide our router from other routers? + + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + + + 13 + + + + Ports + + + + + + + + 0 + 22 + + + + + 16777215 + 22 + + + + Insomnia (prevent system from sleeping) + + + + + + + + 0 + 189 + + + + + 16777215 + 189 + + + + I2PControl interface + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Certificate file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Key file: + + + + + + + + + + Browse… + + + + + + + + + + + + 0 + 0 + + + + + 0 + 105 + + + + + 16777215 + 105 + + + + Websockets server + + + + + 0 + 20 + 85 + 21 + + + + Enable + + + + + + 0 + 40 + 661 + 31 + + + + + + + Address to bind websocket server on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to bind websocket server on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 179 + + + + + 16777215 + 179 + + + + HTTP webconsole + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 321 + 22 + + + + Enable basic HTTP auth + + + + + + 60 + 120 + 601 + 31 + + + + + + + Username: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 60 + 150 + 601 + 31 + + + + + + + Password: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 335 + + + + + 16777215 + 335 + + + + Socks proxy + + + + + 0 + 20 + 97 + 22 + + + + Enabled + + + + + + 0 + 40 + 661 + 31 + + + + + + + IP address to listen on: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 70 + 661 + 31 + + + + + + + Port to listen on: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 100 + 661 + 31 + + + + + + + Keys file: + + + + + + + + + + Browse… + + + + + + + + + 0 + 160 + 661 + 31 + + + + + + + Inbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 190 + 661 + 31 + + + + + + + Inbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 220 + 661 + 31 + + + + + + + Outbound tunnels length: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 250 + 661 + 31 + + + + + + + Outbound tunnels quantity: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 280 + 661 + 31 + + + + + + + Outproxy address: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 310 + 661 + 31 + + + + + + + Outproxy port: + + + + + + + + 80 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 130 + 661 + 31 + + + + + + + Signature type: + + + + + + + + + + Edit + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 06760bb7..4fd1d38f 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -89,7 +89,9 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../daemon/UnixDaemon.cpp \ ../../daemon/UPnP.cpp \ textbrowsertweaked1.cpp \ - pagewithbackbutton.cpp + pagewithbackbutton.cpp \ + widgetlock.cpp \ + widgetlockregistry.cpp #qt creator does not handle this well #SOURCES += $$files(../../libi2pd/*.cpp) @@ -170,7 +172,9 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../daemon/I2PControl.h \ ../../daemon/UPnP.h \ textbrowsertweaked1.h \ - pagewithbackbutton.h + pagewithbackbutton.h \ + widgetlock.h \ + widgetlockregistry.h INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd_client @@ -180,7 +184,8 @@ INCLUDEPATH += . FORMS += mainwindow.ui \ tunnelform.ui \ statusbuttons.ui \ - routercommandswidget.ui + routercommandswidget.ui \ + generalsettingswidget.ui LIBS += -lz diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index ac431672..de32b3cd 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -4,6 +4,7 @@ #include "ui_mainwindow.h" #include "ui_statusbuttons.h" #include "ui_routercommandswidget.h" +#include "ui_generalsettingswidget.h" #include #include #include @@ -38,7 +39,9 @@ MainWindow::MainWindow(QWidget *parent) : ,ui(new Ui::MainWindow) ,statusButtonsUI(new Ui::StatusButtonsForm) ,routerCommandsUI(new Ui::routerCommandsWidget) + ,uiSettings(new Ui::GeneralSettingsContentsForm) ,routerCommandsParent(new QWidget(this)) + ,widgetlocks() ,i2pController(nullptr) ,configItems() ,datadir() @@ -50,6 +53,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); statusButtonsUI->setupUi(ui->statusButtonsPane); routerCommandsUI->setupUi(routerCommandsParent); + uiSettings->setupUi(ui->settingsContents); routerCommandsParent->hide(); ui->verticalLayout_2->addWidget(routerCommandsParent); //,statusHtmlUI(new Ui::StatusHtmlPaneForm) @@ -66,9 +70,8 @@ MainWindow::MainWindow(QWidget *parent) : onResize(); ui->stackedWidget->setCurrentIndex(0); - ui->settingsScrollArea->resize(ui->settingsContentsGridLayout->sizeHint().width()+10,380); + ui->settingsScrollArea->resize(uiSettings->settingsContentsGridLayout->sizeHint().width()+10,380); QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar(); - //QSize szSettContents = ui->settingsContentsGridLayout->minimumSize(); int w = 683; int h = 3060; ui->settingsContents->setFixedSize(w, h); @@ -80,10 +83,6 @@ MainWindow::MainWindow(QWidget *parent) : ui->settingsContents->setPalette(pal); */ - //ui->settingsScrollArea->adjustSize(); - /*ui->tunnelsScrollAreaWidgetContents->setFixedSize( - ui->tunnelsScrollArea->width() - barSett->width(), 0);*/ - #ifndef ANDROID createActions(); createTrayIcon(); @@ -138,142 +137,145 @@ MainWindow::MainWindow(QWidget *parent) : # define OPTION(section,option,defaultValueGetter) ConfigOption(QString(section),QString(option)) - initFileChooser( OPTION("","conf",[](){return "";}), ui->configFileLineEdit, ui->configFileBrowsePushButton); - initFolderChooser( OPTION("","datadir",[]{return "";}), ui->dataFolderLineEdit, ui->dataFolderBrowsePushButton); - initFileChooser( OPTION("","tunconf",[](){return "";}), ui->tunnelsConfigFileLineEdit, ui->tunnelsConfigFileBrowsePushButton); + initFileChooser( OPTION("","conf",[](){return "";}), uiSettings->configFileLineEdit, uiSettings->configFileBrowsePushButton); + initFolderChooser( OPTION("","datadir",[]{return "";}), uiSettings->dataFolderLineEdit, uiSettings->dataFolderBrowsePushButton); + initFileChooser( OPTION("","tunconf",[](){return "";}), uiSettings->tunnelsConfigFileLineEdit, uiSettings->tunnelsConfigFileBrowsePushButton); - initFileChooser( OPTION("","pidfile",[]{return "";}), ui->pidFileLineEdit, ui->pidFileBrowsePushButton); + initFileChooser( OPTION("","pidfile",[]{return "";}), uiSettings->pidFileLineEdit, uiSettings->pidFileBrowsePushButton); daemonOption=initNonGUIOption( OPTION("","daemon",[]{return "";})); serviceOption=initNonGUIOption( OPTION("","service",[]{return "";})); - ui->logDestinationComboBox->clear(); - ui->logDestinationComboBox->insertItems(0, QStringList() + uiSettings->logDestinationComboBox->clear(); + uiSettings->logDestinationComboBox->insertItems(0, QStringList() << QApplication::translate("MainWindow", "stdout", 0) << QApplication::translate("MainWindow", "file", 0) ); - initLogDestinationCombobox( OPTION("","log",[]{return "";}), ui->logDestinationComboBox); + initLogDestinationCombobox( OPTION("","log",[]{return "";}), uiSettings->logDestinationComboBox); - logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), ui->logFileLineEdit, ui->logFileBrowsePushButton); - initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), ui->logLevelComboBox); + logFileNameOption=initFileChooser( OPTION("","logfile",[]{return "";}), uiSettings->logFileLineEdit, uiSettings->logFileBrowsePushButton); + initLogLevelCombobox(OPTION("","loglevel",[]{return "";}), uiSettings->logLevelComboBox); - initIPAddressBox( OPTION("","host",[]{return "";}), ui->routerExternalHostLineEdit, tr("Router external address -> Host")); - initTCPPortBox( OPTION("","port",[]{return "";}), ui->routerExternalPortLineEdit, tr("Router external address -> Port")); + initIPAddressBox( OPTION("","host",[]{return "";}), uiSettings->routerExternalHostLineEdit, tr("Router external address -> Host")); + initTCPPortBox( OPTION("","port",[]{return "";}), uiSettings->routerExternalPortLineEdit, tr("Router external address -> Port")); - initCheckBox( OPTION("","ipv6",[]{return "false";}), ui->ipv6CheckBox); - initCheckBox( OPTION("","notransit",[]{return "false";}), ui->notransitCheckBox); - initCheckBox( OPTION("","floodfill",[]{return "false";}), ui->floodfillCheckBox); - initStringBox( OPTION("","bandwidth",[]{return "";}), ui->bandwidthLineEdit); - initStringBox( OPTION("","family",[]{return "";}), ui->familyLineEdit); - initIntegerBox( OPTION("","netid",[]{return "2";}), ui->netIdLineEdit, tr("NetID")); + initCheckBox( OPTION("","ipv6",[]{return "false";}), uiSettings->ipv6CheckBox); + initCheckBox( OPTION("","notransit",[]{return "false";}), uiSettings->notransitCheckBox); + initCheckBox( OPTION("","floodfill",[]{return "false";}), uiSettings->floodfillCheckBox); + initStringBox( OPTION("","bandwidth",[]{return "";}), uiSettings->bandwidthLineEdit); + initStringBox( OPTION("","family",[]{return "";}), uiSettings->familyLineEdit); + initIntegerBox( OPTION("","netid",[]{return "2";}), uiSettings->netIdLineEdit, tr("NetID")); #ifdef Q_OS_WIN - initCheckBox( OPTION("","insomnia",[]{return "";}), ui->insomniaCheckBox); + initCheckBox( OPTION("","insomnia",[]{return "";}), uiSettings->insomniaCheckBox); initNonGUIOption( OPTION("","svcctl",[]{return "";})); initNonGUIOption( OPTION("","close",[]{return "";})); #else - ui->insomniaCheckBox->setEnabled(false); + uiSettings->insomniaCheckBox->setEnabled(false); #endif - initCheckBox( OPTION("http","enabled",[]{return "true";}), ui->webconsoleEnabledCheckBox); - initIPAddressBox( OPTION("http","address",[]{return "";}), ui->webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); - initTCPPortBox( OPTION("http","port",[]{return "7070";}), ui->webconsolePortLineEdit, tr("HTTP webconsole -> Port")); - initCheckBox( OPTION("http","auth",[]{return "";}), ui->webconsoleBasicAuthCheckBox); - initStringBox( OPTION("http","user",[]{return "i2pd";}), ui->webconsoleUserNameLineEditBasicAuth); - initStringBox( OPTION("http","pass",[]{return "";}), ui->webconsolePasswordLineEditBasicAuth); + initCheckBox( OPTION("http","enabled",[]{return "true";}), uiSettings->webconsoleEnabledCheckBox); + initIPAddressBox( OPTION("http","address",[]{return "";}), uiSettings->webconsoleAddrLineEdit, tr("HTTP webconsole -> IP address")); + initTCPPortBox( OPTION("http","port",[]{return "7070";}), uiSettings->webconsolePortLineEdit, tr("HTTP webconsole -> Port")); + initCheckBox( OPTION("http","auth",[]{return "";}), uiSettings->webconsoleBasicAuthCheckBox); + initStringBox( OPTION("http","user",[]{return "i2pd";}), uiSettings->webconsoleUserNameLineEditBasicAuth); + initStringBox( OPTION("http","pass",[]{return "";}), uiSettings->webconsolePasswordLineEditBasicAuth); - initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), ui->httpProxyEnabledCheckBox); - initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), ui->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); - initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), ui->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); - initFileChooser( OPTION("httpproxy","keys",[]{return "";}), ui->httpProxyKeyFileLineEdit, ui->httpProxyKeyFilePushButton); + initCheckBox( OPTION("httpproxy","enabled",[]{return "";}), uiSettings->httpProxyEnabledCheckBox); + initIPAddressBox( OPTION("httpproxy","address",[]{return "";}), uiSettings->httpProxyAddressLineEdit, tr("HTTP proxy -> IP address")); + initTCPPortBox( OPTION("httpproxy","port",[]{return "4444";}), uiSettings->httpProxyPortLineEdit, tr("HTTP proxy -> Port")); + initFileChooser( OPTION("httpproxy","keys",[]{return "";}), uiSettings->httpProxyKeyFileLineEdit, uiSettings->httpProxyKeyFilePushButton); - initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), ui->comboBox_httpPorxySignatureType); - initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), ui->httpProxyInboundTunnelsLenLineEdit); - initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), ui->httpProxyInboundTunnQuantityLineEdit); - initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), ui->httpProxyOutBoundTunnLenLineEdit); - initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), ui->httpProxyOutboundTunnQuantityLineEdit); + initSignatureTypeCombobox(OPTION("httpproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_httpPorxySignatureType); + initStringBox( OPTION("httpproxy","inbound.length",[]{return "3";}), uiSettings->httpProxyInboundTunnelsLenLineEdit); + initStringBox( OPTION("httpproxy","inbound.quantity",[]{return "5";}), uiSettings->httpProxyInboundTunnQuantityLineEdit); + initStringBox( OPTION("httpproxy","outbound.length",[]{return "3";}), uiSettings->httpProxyOutBoundTunnLenLineEdit); + initStringBox( OPTION("httpproxy","outbound.quantity",[]{return "5";}), uiSettings->httpProxyOutboundTunnQuantityLineEdit); - initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), ui->socksProxyEnabledCheckBox); - initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), ui->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); - initTCPPortBox( OPTION("socksproxy","port",[]{return "4447";}), ui->socksProxyPortLineEdit, tr("Socks proxy -> Port")); - initFileChooser( OPTION("socksproxy","keys",[]{return "";}), ui->socksProxyKeyFileLineEdit, ui->socksProxyKeyFilePushButton); - initSignatureTypeCombobox(OPTION("socksproxy","signaturetype",[]{return "7";}), ui->comboBox_socksProxySignatureType); - initStringBox( OPTION("socksproxy","inbound.length",[]{return "";}), ui->socksProxyInboundTunnelsLenLineEdit); - initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), ui->socksProxyInboundTunnQuantityLineEdit); - initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), ui->socksProxyOutBoundTunnLenLineEdit); - initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), ui->socksProxyOutboundTunnQuantityLineEdit); - initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), ui->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); - initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), ui->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); + initCheckBox( OPTION("socksproxy","enabled",[]{return "";}), uiSettings->socksProxyEnabledCheckBox); + initIPAddressBox( OPTION("socksproxy","address",[]{return "";}), uiSettings->socksProxyAddressLineEdit, tr("Socks proxy -> IP address")); + initTCPPortBox( OPTION("socksproxy","port",[]{return "4447";}), uiSettings->socksProxyPortLineEdit, tr("Socks proxy -> Port")); + initFileChooser( OPTION("socksproxy","keys",[]{return "";}), uiSettings->socksProxyKeyFileLineEdit, uiSettings->socksProxyKeyFilePushButton); + initSignatureTypeCombobox(OPTION("socksproxy","signaturetype",[]{return "7";}), uiSettings->comboBox_socksProxySignatureType); + initStringBox( OPTION("socksproxy","inbound.length",[]{return "";}), uiSettings->socksProxyInboundTunnelsLenLineEdit); + initStringBox( OPTION("socksproxy","inbound.quantity",[]{return "";}), uiSettings->socksProxyInboundTunnQuantityLineEdit); + initStringBox( OPTION("socksproxy","outbound.length",[]{return "";}), uiSettings->socksProxyOutBoundTunnLenLineEdit); + initStringBox( OPTION("socksproxy","outbound.quantity",[]{return "";}), uiSettings->socksProxyOutboundTunnQuantityLineEdit); + initIPAddressBox( OPTION("socksproxy","outproxy",[]{return "";}), uiSettings->outproxyAddressLineEdit, tr("Socks proxy -> Outproxy address")); + initTCPPortBox( OPTION("socksproxy","outproxyport",[]{return "";}), uiSettings->outproxyPortLineEdit, tr("Socks proxy -> Outproxy port")); - initCheckBox( OPTION("sam","enabled",[]{return "false";}), ui->samEnabledCheckBox); - initIPAddressBox( OPTION("sam","address",[]{return "";}), ui->samAddressLineEdit, tr("SAM -> IP address")); - initTCPPortBox( OPTION("sam","port",[]{return "7656";}), ui->samPortLineEdit, tr("SAM -> Port")); + initCheckBox( OPTION("sam","enabled",[]{return "false";}), uiSettings->samEnabledCheckBox); + initIPAddressBox( OPTION("sam","address",[]{return "";}), uiSettings->samAddressLineEdit, tr("SAM -> IP address")); + initTCPPortBox( OPTION("sam","port",[]{return "7656";}), uiSettings->samPortLineEdit, tr("SAM -> Port")); - initCheckBox( OPTION("bob","enabled",[]{return "false";}), ui->bobEnabledCheckBox); - initIPAddressBox( OPTION("bob","address",[]{return "";}), ui->bobAddressLineEdit, tr("BOB -> IP address")); - initTCPPortBox( OPTION("bob","port",[]{return "2827";}), ui->bobPortLineEdit, tr("BOB -> Port")); + initCheckBox( OPTION("bob","enabled",[]{return "false";}), uiSettings->bobEnabledCheckBox); + initIPAddressBox( OPTION("bob","address",[]{return "";}), uiSettings->bobAddressLineEdit, tr("BOB -> IP address")); + initTCPPortBox( OPTION("bob","port",[]{return "2827";}), uiSettings->bobPortLineEdit, tr("BOB -> Port")); - initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), ui->i2cpEnabledCheckBox); - initIPAddressBox( OPTION("i2cp","address",[]{return "";}), ui->i2cpAddressLineEdit, tr("I2CP -> IP address")); - initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), ui->i2cpPortLineEdit, tr("I2CP -> Port")); + initCheckBox( OPTION("i2cp","enabled",[]{return "false";}), uiSettings->i2cpEnabledCheckBox); + initIPAddressBox( OPTION("i2cp","address",[]{return "";}), uiSettings->i2cpAddressLineEdit, tr("I2CP -> IP address")); + initTCPPortBox( OPTION("i2cp","port",[]{return "7654";}), uiSettings->i2cpPortLineEdit, tr("I2CP -> Port")); - initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), ui->i2pControlEnabledCheckBox); - initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), ui->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); - initTCPPortBox( OPTION("i2pcontrol","port",[]{return "7650";}), ui->i2pControlPortLineEdit, tr("I2PControl -> Port")); - initStringBox( OPTION("i2pcontrol","password",[]{return "";}), ui->i2pControlPasswordLineEdit); - initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), ui->i2pControlCertFileLineEdit, ui->i2pControlCertFileBrowsePushButton); - initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), ui->i2pControlKeyFileLineEdit, ui->i2pControlKeyFileBrowsePushButton); + initCheckBox( OPTION("i2pcontrol","enabled",[]{return "false";}), uiSettings->i2pControlEnabledCheckBox); + initIPAddressBox( OPTION("i2pcontrol","address",[]{return "";}), uiSettings->i2pControlAddressLineEdit, tr("I2PControl -> IP address")); + initTCPPortBox( OPTION("i2pcontrol","port",[]{return "7650";}), uiSettings->i2pControlPortLineEdit, tr("I2PControl -> Port")); + initStringBox( OPTION("i2pcontrol","password",[]{return "";}), uiSettings->i2pControlPasswordLineEdit); + initFileChooser( OPTION("i2pcontrol","cert",[]{return "i2pcontrol.crt.pem";}), uiSettings->i2pControlCertFileLineEdit, uiSettings->i2pControlCertFileBrowsePushButton); + initFileChooser( OPTION("i2pcontrol","key",[]{return "i2pcontrol.key.pem";}), uiSettings->i2pControlKeyFileLineEdit, uiSettings->i2pControlKeyFileBrowsePushButton); - initCheckBox( OPTION("upnp","enabled",[]{return "true";}), ui->enableUPnPCheckBox); - initStringBox( OPTION("upnp","name",[]{return "I2Pd";}), ui->upnpNameLineEdit); + initCheckBox( OPTION("upnp","enabled",[]{return "true";}), uiSettings->enableUPnPCheckBox); + initStringBox( OPTION("upnp","name",[]{return "I2Pd";}), uiSettings->upnpNameLineEdit); - initCheckBox( OPTION("precomputation","elgamal",[]{return "false";}), ui->useElGamalPrecomputedTablesCheckBox); + initCheckBox( OPTION("precomputation","elgamal",[]{return "false";}), uiSettings->useElGamalPrecomputedTablesCheckBox); - initCheckBox( OPTION("reseed","verify",[]{return "";}), ui->reseedVerifyCheckBox); - initFileChooser( OPTION("reseed","file",[]{return "";}), ui->reseedFileLineEdit, ui->reseedFileBrowsePushButton); - initStringBox( OPTION("reseed","urls",[]{return "";}), ui->reseedURLsLineEdit); + initCheckBox( OPTION("reseed","verify",[]{return "";}), uiSettings->reseedVerifyCheckBox); + initFileChooser( OPTION("reseed","file",[]{return "";}), uiSettings->reseedFileLineEdit, uiSettings->reseedFileBrowsePushButton); + initStringBox( OPTION("reseed","urls",[]{return "";}), uiSettings->reseedURLsLineEdit); - initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), ui->addressbookDefaultURLLineEdit); - initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), ui->addressbookSubscriptionsURLslineEdit); + initStringBox( OPTION("addressbook","defaulturl",[]{return "";}), uiSettings->addressbookDefaultURLLineEdit); + initStringBox( OPTION("addressbook","subscriptions",[]{return "";}), uiSettings->addressbookSubscriptionsURLslineEdit); - initUInt16Box( OPTION("limits","transittunnels",[]{return "2500";}), ui->maxNumOfTransitTunnelsLineEdit, tr("maxNumberOfTransitTunnels")); - initUInt16Box( OPTION("limits","openfiles",[]{return "0";}), ui->maxNumOfOpenFilesLineEdit, tr("maxNumberOfOpenFiles")); - initUInt32Box( OPTION("limits","coresize",[]{return "0";}), ui->coreFileMaxSizeNumberLineEdit, tr("coreFileMaxSize")); + initUInt16Box( OPTION("limits","transittunnels",[]{return "2500";}), uiSettings->maxNumOfTransitTunnelsLineEdit, tr("maxNumberOfTransitTunnels")); + initUInt16Box( OPTION("limits","openfiles",[]{return "0";}), uiSettings->maxNumOfOpenFilesLineEdit, tr("maxNumberOfOpenFiles")); + initUInt32Box( OPTION("limits","coresize",[]{return "0";}), uiSettings->coreFileMaxSizeNumberLineEdit, tr("coreFileMaxSize")); - initCheckBox( OPTION("trust","enabled",[]{return "false";}), ui->checkBoxTrustEnable); - initStringBox( OPTION("trust","family",[]{return "";}), ui->lineEditTrustFamily); - initStringBox( OPTION("trust","routers",[]{return "";}), ui->lineEditTrustRouters); - initCheckBox( OPTION("trust","hidden",[]{return "false";}), ui->checkBoxTrustHidden); + initCheckBox( OPTION("trust","enabled",[]{return "false";}), uiSettings->checkBoxTrustEnable); + initStringBox( OPTION("trust","family",[]{return "";}), uiSettings->lineEditTrustFamily); + initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters); + initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden); - initCheckBox( OPTION("websockets","enabled",[]{return "false";}), ui->checkBoxWebsocketsEnable); - initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), ui->lineEdit_webSock_addr, tr("Websocket server -> IP address")); - initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), ui->lineEdit_webSock_port, tr("Websocket server -> Port")); + initCheckBox( OPTION("websockets","enabled",[]{return "false";}), uiSettings->checkBoxWebsocketsEnable); + initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), uiSettings->lineEdit_webSock_addr, tr("Websocket server -> IP address")); + initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), uiSettings->lineEdit_webSock_port, tr("Websocket server -> Port")); # undef OPTION + //widgetlocks.add(new widgetlock(widget,lockbtn)); + widgetlocks.add(new widgetlock(uiSettings->logDestinationComboBox,uiSettings->logDestComboEditPushButton)); + widgetlocks.add(new widgetlock(uiSettings->logLevelComboBox,uiSettings->logLevelComboEditPushButton)); + widgetlocks.add(new widgetlock(uiSettings->comboBox_httpPorxySignatureType,uiSettings->httpProxySignTypeComboEditPushButton)); + widgetlocks.add(new widgetlock(uiSettings->comboBox_socksProxySignatureType,uiSettings->socksProxySignTypeComboEditPushButton)); + loadAllConfigs(); - QObject::connect(ui->logDestinationComboBox, SIGNAL(currentIndexChanged(const QString &)), + QObject::connect(uiSettings->logDestinationComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(logDestinationComboBoxValueChanged(const QString &))); - logDestinationComboBoxValueChanged(ui->logDestinationComboBox->currentText()); + logDestinationComboBoxValueChanged(uiSettings->logDestinationComboBox->currentText()); - //tunnelsFormGridLayoutWidget = new QWidget(ui->tunnelsScrollAreaWidgetContents); - //tunnelsFormGridLayoutWidget->setObjectName(QStringLiteral("tunnelsFormGridLayoutWidget")); - //tunnelsFormGridLayoutWidget->setGeometry(QRect(0, 0, 621, 451)); ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, 451)); appendTunnelForms(""); - ui->configFileLineEdit->setEnabled(false); - ui->configFileBrowsePushButton->setEnabled(false); - ui->configFileLineEdit->setText(confpath); - ui->tunnelsConfigFileLineEdit->setText(tunconfpath); + uiSettings->configFileLineEdit->setEnabled(false); + uiSettings->configFileBrowsePushButton->setEnabled(false); + uiSettings->configFileLineEdit->setText(confpath); + uiSettings->tunnelsConfigFileLineEdit->setText(tunconfpath); for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; item->installListeners(this); } - QObject::connect(ui->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), + QObject::connect(uiSettings->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(reloadTunnelsConfigAndUI())); QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased())); @@ -293,8 +295,8 @@ MainWindow::MainWindow(QWidget *parent) : void MainWindow::logDestinationComboBoxValueChanged(const QString & text) { bool stdout = text==QString("stdout"); - ui->logFileLineEdit->setEnabled(!stdout); - ui->logFileBrowsePushButton->setEnabled(!stdout); + uiSettings->logFileLineEdit->setEnabled(!stdout); + uiSettings->logFileBrowsePushButton->setEnabled(!stdout); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 27f1ccc2..88c84dce 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -59,6 +59,9 @@ #include +#include "widgetlockregistry.h" +#include "widgetlock.h" + template bool isType(boost::any& a) { return @@ -329,6 +332,7 @@ namespace Ui { class MainWindow; class StatusButtonsForm; class routerCommandsWidget; + class GeneralSettingsContentsForm; } using namespace i2p::client; @@ -412,12 +416,15 @@ private: Ui::MainWindow* ui; Ui::StatusButtonsForm* statusButtonsUI; Ui::routerCommandsWidget* routerCommandsUI; + Ui::GeneralSettingsContentsForm* uiSettings; TextBrowserTweaked1 * textBrowser; QWidget * routerCommandsParent; PageWithBackButton * pageWithBackButton; TextBrowserTweaked1 * childTextBrowser; + widgetlockregistry widgetlocks; + i2p::qt::Controller* i2pController; protected: diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 16a0822b..cf15155b 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -293,2756 +293,6 @@ 0 - - - - 10 - 10 - 679 - 3052 - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - SAM interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Windows-specific options - - - - - - - - 0 - 44 - - - - - 16777215 - 44 - - - - Cryptography - - - - - 0 - 20 - 661 - 22 - - - - Use ElGamal precomputed tables - - - - - - - - - 0 - 107 - - - - - 16777215 - 107 - - - - Logging - - - Qt::AlignJustify|Qt::AlignTop - - - - - -1 - 19 - 661 - 91 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMaximumSize - - - - - Destination: - - - - - - - - - - Log file: - - - - - - - - - - Browse… - - - - - - - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - Log level: - - - - - - - - Error - - - - - Warn - - - - - Info - - - - - Debug - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 68 - - - - - 16777215 - 68 - - - - UPnP - - - - - 0 - 20 - 97 - 22 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Name i2pd appears in UPnP forwardings list: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - I2CP interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Tunnels configuration file: - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - BOB interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - General options - - - - - - - - 0 - 0 - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Router external address (for incoming connections) - - - Qt::AlignJustify|Qt::AlignTop - - - - - 0 - 20 - 661 - 81 - - - - - QLayout::SetMinAndMaxSize - - - - - QLayout::SetMinAndMaxSize - - - - - Host: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMinAndMaxSize - - - - - Port (leave empty to auto-assign): - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 78 - - - - - 16777215 - 78 - - - - Addressbook settings - - - - - 0 - 20 - 661 - 31 - - - - - - - Addressbook default subscription URL for initial setup: - - - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Addressbook subscriptions URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 280 - - - - - 16777215 - 280 - - - - HTTP proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Signature type: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Various options - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Data folder (for storage of i2pd data — RI, keys, peer profiles, …): - - - - - 0 - 20 - 661 - 31 - - - - - QLayout::SetMaximumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 0 - - - - - 0 - 215 - - - - - 16777215 - 215 - - - - Router options - - - - - 0 - 20 - 661 - 188 - - - - - - - Enable communication through ipv6 - - - - - - - Router will not accept transit tunnels at startup - - - - - - - Router will be floodfill - - - - - - - - - Bandwidth limit (integer): - - - - - - - - - - KBps - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Family (name of a family router belongs to): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - NetID (network ID router belongs to. The main I2P ID is 2): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 0 - 108 - - - - - 16777215 - 108 - - - - Limits - - - - - 0 - 20 - 661 - 31 - - - - - - - Maximum number of transit tunnels: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 50 - 661 - 31 - - - - - - - Maximum number of open files (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 80 - 661 - 31 - - - - - - - Maximum size of core file in Kb (0 — use system limit): - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 48 - - - - - 16777215 - 48 - - - - Pid file: - - - - - 0 - 20 - 661 - 31 - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 98 - - - - - 16777215 - 98 - - - - Reseeding - - - - - 0 - 20 - 661 - 22 - - - - Request SU3 signature verification - - - - - - 0 - 40 - 661 - 31 - - - - - - - SU3 file to reseed from: - - - - - - - - - - Browse… - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Reseed URLs, separated by comma: - - - - - - - - - - - - - - - 0 - 180 - - - - - 16777215 - 180 - - - - Trust options - - - - - 0 - 20 - 661 - 21 - - - - Enable explicit trust options - - - - - - 390 - 40 - 271 - 23 - - - - - - - 0 - 40 - 391 - 42 - - - - Make direct I2P connections only to -routers in specified Family: - - - - - - 0 - 82 - 661 - 42 - - - - Make direct I2P connections only to routers specified here. -Comma separated list of base64 identities: - - - - - - 0 - 124 - 661 - 23 - - - - - - - 0 - 147 - 661 - 21 - - - - Should we hide our router from other routers? - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 13 - - - - Ports - - - - - - - - 0 - 22 - - - - - 16777215 - 22 - - - - Insomnia (prevent system from sleeping) - - - - - - - - 0 - 189 - - - - - 16777215 - 189 - - - - I2PControl interface - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Certificate file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Key file: - - - - - - - - - - Browse… - - - - - - - - - - - - 0 - 0 - - - - - 0 - 46 - - - - - 16777215 - 46 - - - - Configuration file: - - - - - 0 - 18 - 661 - 31 - - - - - QLayout::SetMinimumSize - - - - - - - - Browse… - - - - - - - - - - - - 0 - 110 - - - - - 16777215 - 110 - - - - Websockets server - - - - - 0 - 20 - 85 - 21 - - - - Enable - - - - - - 0 - 40 - 661 - 31 - - - - - - - Address to bind websocket server on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to bind websocket server on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 179 - - - - - 16777215 - 179 - - - - HTTP webconsole - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 321 - 22 - - - - Enable basic HTTP auth - - - - - - 60 - 120 - 601 - 31 - - - - - - - Username: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 60 - 150 - 601 - 31 - - - - - - - Password: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - 0 - 400 - - - - - 16777215 - 400 - - - - Socks proxy - - - - - 0 - 20 - 97 - 22 - - - - Enabled - - - - - - 0 - 40 - 661 - 31 - - - - - - - IP address to listen on: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 70 - 661 - 31 - - - - - - - Port to listen on: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 100 - 661 - 31 - - - - - - - Keys file: - - - - - - - - - - Browse… - - - - - - - - - 0 - 160 - 661 - 31 - - - - - - - Inbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 190 - 661 - 31 - - - - - - - Inbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 220 - 661 - 31 - - - - - - - Outbound tunnels length: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 250 - 661 - 31 - - - - - - - Outbound tunnels quantity: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 280 - 661 - 31 - - - - - - - Outproxy address: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 310 - 661 - 31 - - - - - - - Outproxy port: - - - - - - - - 80 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - 130 - 661 - 31 - - - - - - - Signature type: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - -
diff --git a/qt/i2pd_qt/widgetlock.cpp b/qt/i2pd_qt/widgetlock.cpp new file mode 100644 index 00000000..a601fb36 --- /dev/null +++ b/qt/i2pd_qt/widgetlock.cpp @@ -0,0 +1 @@ +#include "widgetlock.h" diff --git a/qt/i2pd_qt/widgetlock.h b/qt/i2pd_qt/widgetlock.h new file mode 100644 index 00000000..513f328a --- /dev/null +++ b/qt/i2pd_qt/widgetlock.h @@ -0,0 +1,33 @@ +#ifndef WIDGETLOCK_H +#define WIDGETLOCK_H + +#include +#include +#include +#include + +class widgetlock : public QObject { + Q_OBJECT + +private: + QWidget* widget; + QPushButton* lockButton; +public slots: + void lockButtonClicked(bool) { + bool wasEnabled = widget->isEnabled(); + widget->setEnabled(!wasEnabled); + lockButton->setText(widget->isEnabled()?lockButton->tr("Lock"):lockButton->tr("Edit")); + } + +public: + widgetlock(QWidget* widget_, QPushButton* lockButton_): widget(widget_),lockButton(lockButton_) { + widget->setEnabled(false); + lockButton->setText(lockButton->tr("Edit")); + QObject::connect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); + } + virtual ~widgetlock() { + QObject::disconnect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); + } +}; + +#endif // WIDGETLOCK_H diff --git a/qt/i2pd_qt/widgetlockregistry.cpp b/qt/i2pd_qt/widgetlockregistry.cpp new file mode 100644 index 00000000..0d66d327 --- /dev/null +++ b/qt/i2pd_qt/widgetlockregistry.cpp @@ -0,0 +1,2 @@ +#include "widgetlockregistry.h" + diff --git a/qt/i2pd_qt/widgetlockregistry.h b/qt/i2pd_qt/widgetlockregistry.h new file mode 100644 index 00000000..1091af43 --- /dev/null +++ b/qt/i2pd_qt/widgetlockregistry.h @@ -0,0 +1,23 @@ +#ifndef WIDGETLOCKREGISTRY_H +#define WIDGETLOCKREGISTRY_H + +#include +#include + +class widgetlockregistry { + std::vector locks; + +public: + widgetlockregistry() : locks() {} + virtual ~widgetlockregistry() { + while(!locks.empty()) { + delete locks.back(); + locks.pop_back(); + } + } + void add(widgetlock* lock) { + locks.push_back(lock); + } +}; + +#endif // WIDGETLOCKREGISTRY_H From 63e175d3897388985d736626ddb3f3a3b76f5cc8 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 27 Aug 2017 20:37:21 +0800 Subject: [PATCH 17/81] fixed #913 --- qt/i2pd_qt/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index de32b3cd..f699a131 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -766,6 +766,8 @@ void MainWindow::SaveTunnelsConfig() { outfile << out.str().c_str(); outfile.close(); + i2p::client::ClientContext::ReloadConfig(); + } void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) { From fc2ae6f88788a78441b723c5bd9948e10444caf9 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 27 Aug 2017 20:52:55 +0800 Subject: [PATCH 18/81] fixed ReloadConfig(); fixed --log --- qt/i2pd_qt/mainwindow.cpp | 2 +- qt/i2pd_qt/mainwindow.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index f699a131..71d7dca7 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -766,7 +766,7 @@ void MainWindow::SaveTunnelsConfig() { outfile << out.str().c_str(); outfile.close(); - i2p::client::ClientContext::ReloadConfig(); + i2p::client::context.ReloadConfig(); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 88c84dce..c0286d03 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -218,7 +218,9 @@ public: comboBox->setCurrentText(QString(ld)); } virtual void saveToStringStream(std::stringstream& out){ - optionValue=comboBox->currentText().toStdString(); + std::string logDest = comboBox->currentText().toStdString(); + if(logDest==std::string("stdout"))logDest=""; + optionValue=logDest; MainWindowItem::saveToStringStream(out); } virtual bool isValid() { return true; } From 1c3174a277bfe94eca236b4e535c60dd9ec46c91 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 27 Aug 2017 21:16:52 +0800 Subject: [PATCH 19/81] fixed #841 --- android/jni/Application.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/android/jni/Application.mk b/android/jni/Application.mk index e4a2698a..25f2bb71 100755 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -1,6 +1,7 @@ #APP_ABI := all #APP_ABI := armeabi-v7a x86 #APP_ABI := x86 +#APP_ABI := x86_64 APP_ABI := armeabi-v7a #can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there. APP_PLATFORM := android-14 From 3f409d0e285489e5b66caf176e038af0e7fe469b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 09:53:31 -0400 Subject: [PATCH 20/81] add deferred ready checking for destination --- libi2pd/Destination.cpp | 396 ++++++++++++++++++++++------------------ libi2pd/Destination.h | 14 +- 2 files changed, 231 insertions(+), 179 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d45fdf47..5f17856b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,9 +13,10 @@ namespace i2p namespace client { LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map * params): - m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), - m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), - m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service) + m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), + m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), + m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), + m_ReadyCheckTimer(m_Service) { int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH; int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY; @@ -83,77 +84,80 @@ namespace client LeaseSetDestination::~LeaseSetDestination () { - if (m_IsRunning) + if (m_IsRunning) Stop (); if (m_Pool) - i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); + i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); for (auto& it: m_LeaseSetRequests) it.second->Complete (nullptr); - } + } void LeaseSetDestination::Run () { while (m_IsRunning) { try - { + { m_Service.run (); } catch (std::exception& ex) { LogPrint (eLogError, "Destination: runtime exception: ", ex.what ()); - } - } - } + } + } + } bool LeaseSetDestination::Start () - { + { if (!m_IsRunning) - { + { LoadTags (); m_IsRunning = true; m_Pool->SetLocalDestination (shared_from_this ()); - m_Pool->SetActive (true); + m_Pool->SetActive (true); m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT)); m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); m_Thread = new std::thread (std::bind (&LeaseSetDestination::Run, shared_from_this ())); - + m_ReadyCheckTimer.expires_from_now(boost::posix_time::seconds (1)); + m_ReadyCheckTimer.async_wait(std::bind(&LeaseSetDestination::HandleReadyCheckTimer, + shared_from_this (), std::placeholders::_1)); return true; - } + } else return false; } - + bool LeaseSetDestination::Stop () - { + { if (m_IsRunning) - { + { m_CleanupTimer.cancel (); m_PublishConfirmationTimer.cancel (); - m_PublishVerificationTimer.cancel (); + m_PublishVerificationTimer.cancel (); + m_ReadyCheckTimer.cancel (); m_IsRunning = false; if (m_Pool) - { + { m_Pool->SetLocalDestination (nullptr); i2p::tunnel::tunnels.StopTunnelPool (m_Pool); - } + } m_Service.stop (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = 0; - } + } SaveTags (); CleanUp (); // GarlicDestination return true; - } + } else return false; - } - + } + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; @@ -164,7 +168,7 @@ namespace client remoteLS = it->second; } - if (remoteLS) + if (remoteLS) { if (!remoteLS->IsExpired ()) { @@ -193,9 +197,9 @@ namespace client m_RemoteLeaseSets.erase (ident); return nullptr; } - } + } else - { + { auto ls = i2p::data::netdb.FindLeaseSet (ident); if (ls && !ls->IsExpired ()) { @@ -203,7 +207,7 @@ namespace client std::lock_guard _lock(m_RemoteLeaseSetsMutex); m_RemoteLeaseSets[ident] = ls; return ls; - } + } } return nullptr; } @@ -215,11 +219,11 @@ namespace client UpdateLeaseSet (); std::lock_guard l(m_LeaseSetMutex); return m_LeaseSet; - } + } void LeaseSetDestination::SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet) { - { + { std::lock_guard l(m_LeaseSetMutex); m_LeaseSet.reset (newLeaseSet); } @@ -229,21 +233,26 @@ namespace client m_PublishVerificationTimer.cancel (); Publish (); } - } - + } + + void LeaseSetDestination::AddReadyCallback(ReadyCallback cb) + { + m_ReadyCallbacks.push_back(cb); + } + void LeaseSetDestination::UpdateLeaseSet () { - int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels - if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum + int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels + if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum CreateNewLeaseSet (m_Pool->GetInboundTunnels (numTunnels)); - } + } bool LeaseSetDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) { struct { uint8_t k[32], t[32]; - } data; + } data; memcpy (data.k, key, 32); memcpy (data.t, tag, 32); auto s = shared_from_this (); @@ -256,42 +265,42 @@ namespace client void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); + m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); } void LeaseSetDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); + m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); } void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; switch (typeID) - { + { case eI2NPData: HandleDataMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; case eI2NPDeliveryStatus: // we assume tunnel tests non-encrypted HandleDeliveryStatusMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); - break; + break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; case eI2NPDatabaseSearchReply: HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); - break; + break; default: i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); - } - } + } + } void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len) { uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET); size_t offset = DATABASE_STORE_HEADER_SIZE; - if (replyToken) + if (replyToken) { LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore"); offset += 36; @@ -307,8 +316,8 @@ namespace client { leaseSet = it->second; if (leaseSet->IsNewer (buf + offset, len - offset)) - { - leaseSet->Update (buf + offset, len - offset); + { + leaseSet->Update (buf + offset, len - offset); if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) LogPrint (eLogDebug, "Destination: Remote LeaseSet updated"); else @@ -322,7 +331,7 @@ namespace client LogPrint (eLogDebug, "Destination: Remote LeaseSet is older. Not updated"); } else - { + { leaseSet = std::make_shared (buf + offset, len - offset); if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) { @@ -339,18 +348,18 @@ namespace client LogPrint (eLogError, "Destination: New remote LeaseSet failed"); leaseSet = nullptr; } - } - } + } + } else LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped"); - + auto it1 = m_LeaseSetRequests.find (key); if (it1 != m_LeaseSetRequests.end ()) { it1->second->requestTimeoutTimer.cancel (); if (it1->second) it1->second->Complete (leaseSet); m_LeaseSetRequests.erase (it1); - } + } } void LeaseSetDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len) @@ -364,7 +373,7 @@ namespace client auto request = it->second; bool found = false; if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) - { + { for (int i = 0; i < num; i++) { i2p::data::IdentHash peerHash (buf + 33 + i*32); @@ -372,28 +381,28 @@ namespace client { LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); // TODO: recheck this message i2p::data::netdb.RequestDestination (peerHash); - } + } } - + auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); if (floodfill) { LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ()); if (SendLeaseSetRequest (key, floodfill, request)) found = true; - } - } + } + } if (!found) - { + { LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); request->Complete (nullptr); m_LeaseSetRequests.erase (key); - } - } - else + } + } + else LogPrint (eLogWarning, "Destination: Request for ", key.ToBase64 (), " not found"); - } - + } + void LeaseSetDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); @@ -405,20 +414,20 @@ namespace client // schedule verification m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); } else i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msg); - } + } void LeaseSetDestination::SetLeaseSetUpdated () - { + { UpdateLeaseSet (); } - + void LeaseSetDestination::Publish () - { - if (!m_LeaseSet || !m_Pool) + { + if (!m_LeaseSet || !m_Pool) { LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet"); return; @@ -435,9 +444,9 @@ namespace client m_PublishDelayTimer.cancel (); m_PublishDelayTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_MIN_INTERVAL)); m_PublishDelayTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishDelayTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); return; - } + } auto outbound = m_Pool->GetNextOutboundTunnel (); if (!outbound) { @@ -450,28 +459,28 @@ namespace client LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); return; } - auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); + auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); if (!floodfill) { LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); m_ExcludedFloodfills.clear (); return; - } + } m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); + auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, - shared_from_this (), std::placeholders::_1)); - outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); + shared_from_this (), std::placeholders::_1)); + outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); m_LastSubmissionTime = ts; } void LeaseSetDestination::HandlePublishConfirmationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { if (m_PublishReplyToken) { LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); @@ -484,25 +493,25 @@ namespace client void LeaseSetDestination::HandlePublishVerificationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { auto s = shared_from_this (); - RequestLeaseSet (GetIdentHash (), + RequestLeaseSet (GetIdentHash (), // "this" added due to bug in gcc 4.7-4.8 [s,this](std::shared_ptr leaseSet) { - if (leaseSet) + if (leaseSet) { if (s->m_LeaseSet && *s->m_LeaseSet == *leaseSet) { // we got latest LeasetSet LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32()); s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL)); - s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); + s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); return; - } + } else LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", GetIdentHash().ToBase32()); - } + } else LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", GetIdentHash().ToBase32()); // we have to publish again @@ -515,16 +524,16 @@ namespace client { if (ecode != boost::asio::error::operation_aborted) Publish (); - } - + } + bool LeaseSetDestination::RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete) { - if (!m_Pool || !IsReady ()) - { - if (requestComplete) + if (!m_Pool || !IsReady ()) + { + if (requestComplete) m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; - } + } m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete)); return true; } @@ -536,14 +545,14 @@ namespace client { auto it = s->m_LeaseSetRequests.find (dest); if (it != s->m_LeaseSetRequests.end ()) - { - auto requestComplete = it->second; + { + auto requestComplete = it->second; s->m_LeaseSetRequests.erase (it); if (notify && requestComplete) requestComplete->Complete (nullptr); - } - }); + } + }); } - + void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete) { std::set excluded; @@ -564,28 +573,28 @@ namespace client m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); } - } + } else // duplicate { LogPrint (eLogInfo, "Destination: Request of LeaseSet ", dest.ToBase64 (), " is pending already"); if (ts > ret.first->second->requestTime + MAX_LEASESET_REQUEST_TIMEOUT) - { + { // something went wrong m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); } else if (requestComplete) ret.first->second->requestComplete.push_back (requestComplete); - } - } + } + } else - { + { LogPrint (eLogError, "Destination: Can't request LeaseSet, no floodfills found"); if (requestComplete) requestComplete (nullptr); - } - } - - bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, + } + } + + bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) @@ -594,36 +603,36 @@ namespace client if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); - + if (request->replyTunnel && request->outboundTunnel) - { + { request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTimeoutTimer.cancel (); uint8_t replyKey[32], replyTag[32]; - RAND_bytes (replyKey, 32); // random session key + RAND_bytes (replyKey, 32); // random session key RAND_bytes (replyTag, 32); // random session tag AddSessionKey (replyKey, replyTag); auto msg = WrapMessage (nextFloodfill, - CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag)); request->outboundTunnel->SendTunnelDataMsg ( { - i2p::tunnel::TunnelMessageBlock - { + i2p::tunnel::TunnelMessageBlock + { i2p::tunnel::eDeliveryTypeRouter, nextFloodfill->GetIdentHash (), 0, msg } - }); + }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); request->requestTimeoutTimer.async_wait (std::bind (&LeaseSetDestination::HandleRequestTimoutTimer, shared_from_this (), std::placeholders::_1, dest)); - } + } else return false; return true; - } + } void LeaseSetDestination::HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest) { @@ -641,26 +650,26 @@ namespace client { // reset tunnels, because one them might fail it->second->outboundTunnel = nullptr; - it->second->replyTunnel = nullptr; + it->second->replyTunnel = nullptr; done = !SendLeaseSetRequest (dest, floodfill, it->second); } else done = true; } else - { + { LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); done = true; } - + if (done) { - auto requestComplete = it->second; + auto requestComplete = it->second; m_LeaseSetRequests.erase (it); if (requestComplete) requestComplete->Complete (nullptr); - } - } - } + } + } + } } void LeaseSetDestination::HandleCleanupTimer (const boost::system::error_code& ecode) @@ -674,7 +683,31 @@ namespace client m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, shared_from_this (), std::placeholders::_1)); } - } + } + + void LeaseSetDestination::HandleReadyCheckTimer(const boost::system::error_code & ec) + { + if (ec != boost::asio::error::operation_aborted) + { + // TODO: locking ? + if(IsReady()) + { + for (auto & itr : m_ReadyCallbacks) + { + itr(ec); + } + m_ReadyCallbacks.clear(); + } + } + else + { + for (auto & itr : m_ReadyCallbacks) + { + itr(ec); + } + m_ReadyCallbacks.clear(); + } + } void LeaseSetDestination::CleanupRemoteLeaseSets () { @@ -686,11 +719,11 @@ namespace client { LogPrint (eLogWarning, "Destination: Remote LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired"); it = m_RemoteLeaseSets.erase (it); - } - else + } + else ++it; } - } + } ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (isPublic, params), @@ -703,26 +736,26 @@ namespace client i2p::crypto::GenerateElGamalKeyPair(m_EncryptionPrivateKey, m_EncryptionPublicKey); if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); - } + } - ClientDestination::~ClientDestination () + ClientDestination::~ClientDestination () { - } - + } + bool ClientDestination::Start () { if (LeaseSetDestination::Start ()) - { + { m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: - m_StreamingDestination->Start (); + m_StreamingDestination->Start (); for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); return true; - } + } else return false; - } - + } + bool ClientDestination::Stop () { if (LeaseSetDestination::Stop ()) @@ -732,21 +765,21 @@ namespace client //m_StreamingDestination->SetOwner (nullptr); m_StreamingDestination = nullptr; for (auto& it: m_StreamingDestinationsByPorts) - { + { it.second->Stop (); //it.second->SetOwner (nullptr); } m_StreamingDestinationsByPorts.clear (); if (m_DatagramDestination) - { + { delete m_DatagramDestination; m_DatagramDestination = nullptr; - } + } return true; } else return false; - } + } #ifdef I2LUA void ClientDestination::Ready(ReadyPromise & p) @@ -773,14 +806,14 @@ namespace client ScheduleCheckForReady(p); } #endif - + void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); buf += 4; // we assume I2CP payload uint16_t fromPort = bufbe16toh (buf + 4), // source - toPort = bufbe16toh (buf + 6); // destination + toPort = bufbe16toh (buf + 6); // destination switch (buf[9]) { case PROTOCOL_TYPE_STREAMING: @@ -804,28 +837,41 @@ namespace client LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]); } } - - void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) + + void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) { - if (!streamRequestComplete) + if (!streamRequestComplete) { LogPrint (eLogError, "Destination: request callback is not specified in CreateStream"); return; - } - auto leaseSet = FindLeaseSet (dest); - if (leaseSet) - streamRequestComplete(CreateStream (leaseSet, port)); + } + if(IsReady()) + { + auto leaseSet = FindLeaseSet (dest); + if (leaseSet) + streamRequestComplete(CreateStream (leaseSet, port)); + else + { + auto s = GetSharedFromThis (); + RequestDestination (dest, + [s, streamRequestComplete, port](std::shared_ptr ls) + { + if (ls) + streamRequestComplete(s->CreateStream (ls, port)); + else + streamRequestComplete (nullptr); + }); + } + } else { - auto s = GetSharedFromThis (); - RequestDestination (dest, - [s, streamRequestComplete, port](std::shared_ptr ls) - { - if (ls) - streamRequestComplete(s->CreateStream (ls, port)); + // call if tunnel is not ready + AddReadyCallback([&](const boost::system::error_code & ec) { + if(ec) + streamRequestComplete(nullptr); else - streamRequestComplete (nullptr); - }); + CreateStream(streamRequestComplete, dest, port); + }); } } @@ -837,18 +883,18 @@ namespace client return nullptr; } - std::shared_ptr ClientDestination::GetStreamingDestination (int port) const - { - if (port) + std::shared_ptr ClientDestination::GetStreamingDestination (int port) const + { + if (port) { auto it = m_StreamingDestinationsByPorts.find (port); if (it != m_StreamingDestinationsByPorts.end ()) return it->second; - } + } // if port is zero or not found, use default destination - return m_StreamingDestination; + return m_StreamingDestination; } - + void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor) { if (m_StreamingDestination) @@ -860,35 +906,35 @@ namespace client if (m_StreamingDestination) m_StreamingDestination->ResetAcceptor (); } - + bool ClientDestination::IsAcceptingStreams () const { if (m_StreamingDestination) return m_StreamingDestination->IsAcceptorSet (); return false; - } + } void ClientDestination::AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor) { if (m_StreamingDestination) m_StreamingDestination->AcceptOnce (acceptor); - } - + } + std::shared_ptr ClientDestination::CreateStreamingDestination (int port, bool gzip) { - auto dest = std::make_shared (GetSharedFromThis (), port, gzip); + auto dest = std::make_shared (GetSharedFromThis (), port, gzip); if (port) m_StreamingDestinationsByPorts[port] = dest; - else // update default + else // update default m_StreamingDestination = dest; return dest; - } - + } + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination () { if (m_DatagramDestination == nullptr) m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis ()); - return m_DatagramDestination; + return m_DatagramDestination; } std::vector > ClientDestination::GetAllStreams () const @@ -898,12 +944,12 @@ namespace client { for (auto& it: m_StreamingDestination->GetStreams ()) ret.push_back (it.second); - } + } for (auto& it: m_StreamingDestinationsByPorts) for (auto& it1: it.second->GetStreams ()) ret.push_back (it1.second); return ret; - } + } void ClientDestination::PersistTemporaryKeys () { @@ -927,7 +973,7 @@ namespace client return; } LogPrint(eLogError, "Destinations: Can't save keys to ", path); - } + } void ClientDestination::CreateNewLeaseSet (std::vector > tunnels) { @@ -935,7 +981,7 @@ namespace client // sign Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); // TODO SetLeaseSet (leaseSet); - } + } void ClientDestination::CleanupDestination () { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index ef7437fb..4e299322 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -63,6 +63,7 @@ namespace client public std::enable_shared_from_this { typedef std::function leaseSet)> RequestComplete; + typedef std::function ReadyCallback; // leaseSet = nullptr means not found struct LeaseSetRequest { @@ -108,6 +109,8 @@ namespace client void ProcessDeliveryStatusMessage (std::shared_ptr msg); void SetLeaseSetUpdated (); + void AddReadyCallback(ReadyCallback cb); + protected: void SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet); @@ -131,7 +134,8 @@ namespace client void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); - void HandleCleanupTimer (const boost::system::error_code& ecode); + void HandleCleanupTimer (const boost::system::error_code& ecode); + void HandleReadyCheckTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); private: @@ -152,7 +156,9 @@ namespace client std::set m_ExcludedFloodfills; // for publishing boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, - m_PublishDelayTimer, m_CleanupTimer; + m_PublishDelayTimer, m_CleanupTimer, m_ReadyCheckTimer; + + std::vector m_ReadyCallbacks; public: @@ -182,9 +188,9 @@ namespace client void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; // ref counter - int Acquire () { return ++m_RefCounter; }; + int Acquire () { return ++m_RefCounter; }; int Release () { return --m_RefCounter; }; - int GetRefCounter () const { return m_RefCounter; }; + int GetRefCounter () const { return m_RefCounter; }; // streaming std::shared_ptr CreateStreamingDestination (int port, bool gzip = true); // additional From f87a51034e187ae4ca192bff224ba8bc0f362d67 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:07:09 -0400 Subject: [PATCH 21/81] re trigger timer --- libi2pd/Destination.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 5f17856b..f45e6a8a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -698,6 +698,9 @@ namespace client } m_ReadyCallbacks.clear(); } + m_ReadyCheckTimer.expires_from_now(boost::posix_time::seconds (1)); + m_ReadyCheckTimer.async_wait(std::bind(&LeaseSetDestination::HandleReadyCheckTimer, + shared_from_this (), std::placeholders::_1)); } else { @@ -730,7 +733,7 @@ namespace client m_Keys (keys), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) { - if (isPublic) + if (isPublic) PersistTemporaryKeys (); else i2p::crypto::GenerateElGamalKeyPair(m_EncryptionPrivateKey, m_EncryptionPublicKey); From 897cfad399851055583d330bb7f0d4c2025fe786 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:12:59 -0400 Subject: [PATCH 22/81] tabify --- libi2pd/Destination.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 4e299322..88770a11 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -63,7 +63,7 @@ namespace client public std::enable_shared_from_this { typedef std::function leaseSet)> RequestComplete; - typedef std::function ReadyCallback; + typedef std::function ReadyCallback; // leaseSet = nullptr means not found struct LeaseSetRequest { @@ -109,7 +109,7 @@ namespace client void ProcessDeliveryStatusMessage (std::shared_ptr msg); void SetLeaseSetUpdated (); - void AddReadyCallback(ReadyCallback cb); + void AddReadyCallback(ReadyCallback cb); protected: @@ -134,8 +134,8 @@ namespace client void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); - void HandleCleanupTimer (const boost::system::error_code& ecode); - void HandleReadyCheckTimer (const boost::system::error_code& ecode); + void HandleCleanupTimer (const boost::system::error_code& ecode); + void HandleReadyCheckTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); private: @@ -158,7 +158,7 @@ namespace client boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, m_PublishDelayTimer, m_CleanupTimer, m_ReadyCheckTimer; - std::vector m_ReadyCallbacks; + std::vector m_ReadyCallbacks; public: From 7af3b751d45c6038dfbd6bd01b022a10934d43ea Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:14:06 -0400 Subject: [PATCH 23/81] clarify --- libi2pd/Destination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f45e6a8a..a32e2ffa 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -868,7 +868,7 @@ namespace client } else { - // call if tunnel is not ready + // call later if tunnel is not ready AddReadyCallback([&](const boost::system::error_code & ec) { if(ec) streamRequestComplete(nullptr); From 4e4def4fb90f8a0cb1faf61a935479f7527168bf Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:24:07 -0400 Subject: [PATCH 24/81] use shared from this --- libi2pd/Destination.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a32e2ffa..e544b082 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -869,11 +869,12 @@ namespace client else { // call later if tunnel is not ready - AddReadyCallback([&](const boost::system::error_code & ec) { + auto s = GetSharedFromThis(); + AddReadyCallback([s, streamRequestComplete, dest, port](const boost::system::error_code & ec) { if(ec) streamRequestComplete(nullptr); else - CreateStream(streamRequestComplete, dest, port); + s->CreateStream(streamRequestComplete, dest, port); }); } } From a6f62a99b9583395eaf242fe4d2c56c0d4efa06a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:37:53 -0400 Subject: [PATCH 25/81] Revert "use shared from this" This reverts commit 4e4def4fb90f8a0cb1faf61a935479f7527168bf. --- libi2pd/Destination.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index e544b082..a32e2ffa 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -869,12 +869,11 @@ namespace client else { // call later if tunnel is not ready - auto s = GetSharedFromThis(); - AddReadyCallback([s, streamRequestComplete, dest, port](const boost::system::error_code & ec) { + AddReadyCallback([&](const boost::system::error_code & ec) { if(ec) streamRequestComplete(nullptr); else - s->CreateStream(streamRequestComplete, dest, port); + CreateStream(streamRequestComplete, dest, port); }); } } From 27782ceddd2c14c389a2772fa74e8e2c68aae90a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:37:56 -0400 Subject: [PATCH 26/81] Revert "clarify" This reverts commit 7af3b751d45c6038dfbd6bd01b022a10934d43ea. --- libi2pd/Destination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a32e2ffa..f45e6a8a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -868,7 +868,7 @@ namespace client } else { - // call later if tunnel is not ready + // call if tunnel is not ready AddReadyCallback([&](const boost::system::error_code & ec) { if(ec) streamRequestComplete(nullptr); From d7e4deab4e0a1823128dd03fbba22aec52f8d43b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:37:57 -0400 Subject: [PATCH 27/81] Revert "tabify" This reverts commit 897cfad399851055583d330bb7f0d4c2025fe786. --- libi2pd/Destination.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 88770a11..4e299322 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -63,7 +63,7 @@ namespace client public std::enable_shared_from_this { typedef std::function leaseSet)> RequestComplete; - typedef std::function ReadyCallback; + typedef std::function ReadyCallback; // leaseSet = nullptr means not found struct LeaseSetRequest { @@ -109,7 +109,7 @@ namespace client void ProcessDeliveryStatusMessage (std::shared_ptr msg); void SetLeaseSetUpdated (); - void AddReadyCallback(ReadyCallback cb); + void AddReadyCallback(ReadyCallback cb); protected: @@ -134,8 +134,8 @@ namespace client void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); - void HandleCleanupTimer (const boost::system::error_code& ecode); - void HandleReadyCheckTimer (const boost::system::error_code& ecode); + void HandleCleanupTimer (const boost::system::error_code& ecode); + void HandleReadyCheckTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); private: @@ -158,7 +158,7 @@ namespace client boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, m_PublishDelayTimer, m_CleanupTimer, m_ReadyCheckTimer; - std::vector m_ReadyCallbacks; + std::vector m_ReadyCallbacks; public: From 41ce9d47e5d9206bd512bcabc3190c67a83d4e1b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:37:58 -0400 Subject: [PATCH 28/81] Revert "re trigger timer" This reverts commit f87a51034e187ae4ca192bff224ba8bc0f362d67. --- libi2pd/Destination.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index f45e6a8a..5f17856b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -698,9 +698,6 @@ namespace client } m_ReadyCallbacks.clear(); } - m_ReadyCheckTimer.expires_from_now(boost::posix_time::seconds (1)); - m_ReadyCheckTimer.async_wait(std::bind(&LeaseSetDestination::HandleReadyCheckTimer, - shared_from_this (), std::placeholders::_1)); } else { @@ -733,7 +730,7 @@ namespace client m_Keys (keys), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) { - if (isPublic) + if (isPublic) PersistTemporaryKeys (); else i2p::crypto::GenerateElGamalKeyPair(m_EncryptionPrivateKey, m_EncryptionPublicKey); From 416589cc930f0646b02d0db239f60d55aa3db05a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 10:38:26 -0400 Subject: [PATCH 29/81] Revert "add deferred ready checking for destination" This reverts commit 3f409d0e285489e5b66caf176e038af0e7fe469b. --- libi2pd/Destination.cpp | 396 ++++++++++++++++++---------------------- libi2pd/Destination.h | 14 +- 2 files changed, 179 insertions(+), 231 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 5f17856b..d45fdf47 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,10 +13,9 @@ namespace i2p namespace client { LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map * params): - m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), - m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), - m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service), - m_ReadyCheckTimer(m_Service) + m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), + m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), + m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service) { int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH; int inQty = DEFAULT_INBOUND_TUNNELS_QUANTITY; @@ -84,80 +83,77 @@ namespace client LeaseSetDestination::~LeaseSetDestination () { - if (m_IsRunning) + if (m_IsRunning) Stop (); if (m_Pool) - i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); + i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); for (auto& it: m_LeaseSetRequests) it.second->Complete (nullptr); - } + } void LeaseSetDestination::Run () { while (m_IsRunning) { try - { + { m_Service.run (); } catch (std::exception& ex) { LogPrint (eLogError, "Destination: runtime exception: ", ex.what ()); - } - } - } + } + } + } bool LeaseSetDestination::Start () - { + { if (!m_IsRunning) - { + { LoadTags (); m_IsRunning = true; m_Pool->SetLocalDestination (shared_from_this ()); - m_Pool->SetActive (true); + m_Pool->SetActive (true); m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT)); m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); m_Thread = new std::thread (std::bind (&LeaseSetDestination::Run, shared_from_this ())); - m_ReadyCheckTimer.expires_from_now(boost::posix_time::seconds (1)); - m_ReadyCheckTimer.async_wait(std::bind(&LeaseSetDestination::HandleReadyCheckTimer, - shared_from_this (), std::placeholders::_1)); + return true; - } + } else return false; } - + bool LeaseSetDestination::Stop () - { + { if (m_IsRunning) - { + { m_CleanupTimer.cancel (); m_PublishConfirmationTimer.cancel (); - m_PublishVerificationTimer.cancel (); - m_ReadyCheckTimer.cancel (); + m_PublishVerificationTimer.cancel (); m_IsRunning = false; if (m_Pool) - { + { m_Pool->SetLocalDestination (nullptr); i2p::tunnel::tunnels.StopTunnelPool (m_Pool); - } + } m_Service.stop (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = 0; - } + } SaveTags (); CleanUp (); // GarlicDestination return true; - } + } else return false; - } - + } + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; @@ -168,7 +164,7 @@ namespace client remoteLS = it->second; } - if (remoteLS) + if (remoteLS) { if (!remoteLS->IsExpired ()) { @@ -197,9 +193,9 @@ namespace client m_RemoteLeaseSets.erase (ident); return nullptr; } - } + } else - { + { auto ls = i2p::data::netdb.FindLeaseSet (ident); if (ls && !ls->IsExpired ()) { @@ -207,7 +203,7 @@ namespace client std::lock_guard _lock(m_RemoteLeaseSetsMutex); m_RemoteLeaseSets[ident] = ls; return ls; - } + } } return nullptr; } @@ -219,11 +215,11 @@ namespace client UpdateLeaseSet (); std::lock_guard l(m_LeaseSetMutex); return m_LeaseSet; - } + } void LeaseSetDestination::SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet) { - { + { std::lock_guard l(m_LeaseSetMutex); m_LeaseSet.reset (newLeaseSet); } @@ -233,26 +229,21 @@ namespace client m_PublishVerificationTimer.cancel (); Publish (); } - } - - void LeaseSetDestination::AddReadyCallback(ReadyCallback cb) - { - m_ReadyCallbacks.push_back(cb); - } - + } + void LeaseSetDestination::UpdateLeaseSet () { - int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels - if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum + int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels + if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum CreateNewLeaseSet (m_Pool->GetInboundTunnels (numTunnels)); - } + } bool LeaseSetDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) { struct { uint8_t k[32], t[32]; - } data; + } data; memcpy (data.k, key, 32); memcpy (data.t, tag, 32); auto s = shared_from_this (); @@ -265,42 +256,42 @@ namespace client void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); + m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); } void LeaseSetDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); + m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); } void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; switch (typeID) - { + { case eI2NPData: HandleDataMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; case eI2NPDeliveryStatus: // we assume tunnel tests non-encrypted HandleDeliveryStatusMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); - break; + break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; case eI2NPDatabaseSearchReply: HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); - break; + break; default: i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); - } - } + } + } void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len) { uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET); size_t offset = DATABASE_STORE_HEADER_SIZE; - if (replyToken) + if (replyToken) { LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore"); offset += 36; @@ -316,8 +307,8 @@ namespace client { leaseSet = it->second; if (leaseSet->IsNewer (buf + offset, len - offset)) - { - leaseSet->Update (buf + offset, len - offset); + { + leaseSet->Update (buf + offset, len - offset); if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) LogPrint (eLogDebug, "Destination: Remote LeaseSet updated"); else @@ -331,7 +322,7 @@ namespace client LogPrint (eLogDebug, "Destination: Remote LeaseSet is older. Not updated"); } else - { + { leaseSet = std::make_shared (buf + offset, len - offset); if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) { @@ -348,18 +339,18 @@ namespace client LogPrint (eLogError, "Destination: New remote LeaseSet failed"); leaseSet = nullptr; } - } - } + } + } else LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped"); - + auto it1 = m_LeaseSetRequests.find (key); if (it1 != m_LeaseSetRequests.end ()) { it1->second->requestTimeoutTimer.cancel (); if (it1->second) it1->second->Complete (leaseSet); m_LeaseSetRequests.erase (it1); - } + } } void LeaseSetDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len) @@ -373,7 +364,7 @@ namespace client auto request = it->second; bool found = false; if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) - { + { for (int i = 0; i < num; i++) { i2p::data::IdentHash peerHash (buf + 33 + i*32); @@ -381,28 +372,28 @@ namespace client { LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); // TODO: recheck this message i2p::data::netdb.RequestDestination (peerHash); - } + } } - + auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); if (floodfill) { LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ()); if (SendLeaseSetRequest (key, floodfill, request)) found = true; - } - } + } + } if (!found) - { + { LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); request->Complete (nullptr); m_LeaseSetRequests.erase (key); - } - } - else + } + } + else LogPrint (eLogWarning, "Destination: Request for ", key.ToBase64 (), " not found"); - } - + } + void LeaseSetDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); @@ -414,20 +405,20 @@ namespace client // schedule verification m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); } else i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msg); - } + } void LeaseSetDestination::SetLeaseSetUpdated () - { + { UpdateLeaseSet (); } - + void LeaseSetDestination::Publish () - { - if (!m_LeaseSet || !m_Pool) + { + if (!m_LeaseSet || !m_Pool) { LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet"); return; @@ -444,9 +435,9 @@ namespace client m_PublishDelayTimer.cancel (); m_PublishDelayTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_MIN_INTERVAL)); m_PublishDelayTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishDelayTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); return; - } + } auto outbound = m_Pool->GetNextOutboundTunnel (); if (!outbound) { @@ -459,28 +450,28 @@ namespace client LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); return; } - auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); + auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); if (!floodfill) { LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); m_ExcludedFloodfills.clear (); return; - } + } m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); + auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, - shared_from_this (), std::placeholders::_1)); - outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); + shared_from_this (), std::placeholders::_1)); + outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); m_LastSubmissionTime = ts; } void LeaseSetDestination::HandlePublishConfirmationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { if (m_PublishReplyToken) { LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); @@ -493,25 +484,25 @@ namespace client void LeaseSetDestination::HandlePublishVerificationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { auto s = shared_from_this (); - RequestLeaseSet (GetIdentHash (), + RequestLeaseSet (GetIdentHash (), // "this" added due to bug in gcc 4.7-4.8 [s,this](std::shared_ptr leaseSet) { - if (leaseSet) + if (leaseSet) { if (s->m_LeaseSet && *s->m_LeaseSet == *leaseSet) { // we got latest LeasetSet LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32()); s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL)); - s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); + s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); return; - } + } else LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", GetIdentHash().ToBase32()); - } + } else LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", GetIdentHash().ToBase32()); // we have to publish again @@ -524,16 +515,16 @@ namespace client { if (ecode != boost::asio::error::operation_aborted) Publish (); - } - + } + bool LeaseSetDestination::RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete) { - if (!m_Pool || !IsReady ()) - { - if (requestComplete) + if (!m_Pool || !IsReady ()) + { + if (requestComplete) m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; - } + } m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete)); return true; } @@ -545,14 +536,14 @@ namespace client { auto it = s->m_LeaseSetRequests.find (dest); if (it != s->m_LeaseSetRequests.end ()) - { - auto requestComplete = it->second; + { + auto requestComplete = it->second; s->m_LeaseSetRequests.erase (it); if (notify && requestComplete) requestComplete->Complete (nullptr); - } - }); + } + }); } - + void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete) { std::set excluded; @@ -573,28 +564,28 @@ namespace client m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); } - } + } else // duplicate { LogPrint (eLogInfo, "Destination: Request of LeaseSet ", dest.ToBase64 (), " is pending already"); if (ts > ret.first->second->requestTime + MAX_LEASESET_REQUEST_TIMEOUT) - { + { // something went wrong m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); } else if (requestComplete) ret.first->second->requestComplete.push_back (requestComplete); - } - } + } + } else - { + { LogPrint (eLogError, "Destination: Can't request LeaseSet, no floodfills found"); if (requestComplete) requestComplete (nullptr); - } - } - - bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, + } + } + + bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) @@ -603,36 +594,36 @@ namespace client if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); - + if (request->replyTunnel && request->outboundTunnel) - { + { request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTimeoutTimer.cancel (); uint8_t replyKey[32], replyTag[32]; - RAND_bytes (replyKey, 32); // random session key + RAND_bytes (replyKey, 32); // random session key RAND_bytes (replyTag, 32); // random session tag AddSessionKey (replyKey, replyTag); auto msg = WrapMessage (nextFloodfill, - CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag)); request->outboundTunnel->SendTunnelDataMsg ( { - i2p::tunnel::TunnelMessageBlock - { + i2p::tunnel::TunnelMessageBlock + { i2p::tunnel::eDeliveryTypeRouter, nextFloodfill->GetIdentHash (), 0, msg } - }); + }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); request->requestTimeoutTimer.async_wait (std::bind (&LeaseSetDestination::HandleRequestTimoutTimer, shared_from_this (), std::placeholders::_1, dest)); - } + } else return false; return true; - } + } void LeaseSetDestination::HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest) { @@ -650,26 +641,26 @@ namespace client { // reset tunnels, because one them might fail it->second->outboundTunnel = nullptr; - it->second->replyTunnel = nullptr; + it->second->replyTunnel = nullptr; done = !SendLeaseSetRequest (dest, floodfill, it->second); } else done = true; } else - { + { LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); done = true; } - + if (done) { - auto requestComplete = it->second; + auto requestComplete = it->second; m_LeaseSetRequests.erase (it); if (requestComplete) requestComplete->Complete (nullptr); - } - } - } + } + } + } } void LeaseSetDestination::HandleCleanupTimer (const boost::system::error_code& ecode) @@ -683,31 +674,7 @@ namespace client m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, shared_from_this (), std::placeholders::_1)); } - } - - void LeaseSetDestination::HandleReadyCheckTimer(const boost::system::error_code & ec) - { - if (ec != boost::asio::error::operation_aborted) - { - // TODO: locking ? - if(IsReady()) - { - for (auto & itr : m_ReadyCallbacks) - { - itr(ec); - } - m_ReadyCallbacks.clear(); - } - } - else - { - for (auto & itr : m_ReadyCallbacks) - { - itr(ec); - } - m_ReadyCallbacks.clear(); - } - } + } void LeaseSetDestination::CleanupRemoteLeaseSets () { @@ -719,11 +686,11 @@ namespace client { LogPrint (eLogWarning, "Destination: Remote LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired"); it = m_RemoteLeaseSets.erase (it); - } - else + } + else ++it; } - } + } ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (isPublic, params), @@ -736,26 +703,26 @@ namespace client i2p::crypto::GenerateElGamalKeyPair(m_EncryptionPrivateKey, m_EncryptionPublicKey); if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); - } + } - ClientDestination::~ClientDestination () + ClientDestination::~ClientDestination () { - } - + } + bool ClientDestination::Start () { if (LeaseSetDestination::Start ()) - { + { m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: - m_StreamingDestination->Start (); + m_StreamingDestination->Start (); for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); return true; - } + } else return false; - } - + } + bool ClientDestination::Stop () { if (LeaseSetDestination::Stop ()) @@ -765,21 +732,21 @@ namespace client //m_StreamingDestination->SetOwner (nullptr); m_StreamingDestination = nullptr; for (auto& it: m_StreamingDestinationsByPorts) - { + { it.second->Stop (); //it.second->SetOwner (nullptr); } m_StreamingDestinationsByPorts.clear (); if (m_DatagramDestination) - { + { delete m_DatagramDestination; m_DatagramDestination = nullptr; - } + } return true; } else return false; - } + } #ifdef I2LUA void ClientDestination::Ready(ReadyPromise & p) @@ -806,14 +773,14 @@ namespace client ScheduleCheckForReady(p); } #endif - + void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); buf += 4; // we assume I2CP payload uint16_t fromPort = bufbe16toh (buf + 4), // source - toPort = bufbe16toh (buf + 6); // destination + toPort = bufbe16toh (buf + 6); // destination switch (buf[9]) { case PROTOCOL_TYPE_STREAMING: @@ -837,41 +804,28 @@ namespace client LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]); } } - - void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) + + void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) { - if (!streamRequestComplete) + if (!streamRequestComplete) { LogPrint (eLogError, "Destination: request callback is not specified in CreateStream"); return; - } - if(IsReady()) - { - auto leaseSet = FindLeaseSet (dest); - if (leaseSet) - streamRequestComplete(CreateStream (leaseSet, port)); - else - { - auto s = GetSharedFromThis (); - RequestDestination (dest, - [s, streamRequestComplete, port](std::shared_ptr ls) - { - if (ls) - streamRequestComplete(s->CreateStream (ls, port)); - else - streamRequestComplete (nullptr); - }); - } - } + } + auto leaseSet = FindLeaseSet (dest); + if (leaseSet) + streamRequestComplete(CreateStream (leaseSet, port)); else { - // call if tunnel is not ready - AddReadyCallback([&](const boost::system::error_code & ec) { - if(ec) - streamRequestComplete(nullptr); + auto s = GetSharedFromThis (); + RequestDestination (dest, + [s, streamRequestComplete, port](std::shared_ptr ls) + { + if (ls) + streamRequestComplete(s->CreateStream (ls, port)); else - CreateStream(streamRequestComplete, dest, port); - }); + streamRequestComplete (nullptr); + }); } } @@ -883,18 +837,18 @@ namespace client return nullptr; } - std::shared_ptr ClientDestination::GetStreamingDestination (int port) const - { - if (port) + std::shared_ptr ClientDestination::GetStreamingDestination (int port) const + { + if (port) { auto it = m_StreamingDestinationsByPorts.find (port); if (it != m_StreamingDestinationsByPorts.end ()) return it->second; - } + } // if port is zero or not found, use default destination - return m_StreamingDestination; + return m_StreamingDestination; } - + void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor) { if (m_StreamingDestination) @@ -906,35 +860,35 @@ namespace client if (m_StreamingDestination) m_StreamingDestination->ResetAcceptor (); } - + bool ClientDestination::IsAcceptingStreams () const { if (m_StreamingDestination) return m_StreamingDestination->IsAcceptorSet (); return false; - } + } void ClientDestination::AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor) { if (m_StreamingDestination) m_StreamingDestination->AcceptOnce (acceptor); - } - + } + std::shared_ptr ClientDestination::CreateStreamingDestination (int port, bool gzip) { - auto dest = std::make_shared (GetSharedFromThis (), port, gzip); + auto dest = std::make_shared (GetSharedFromThis (), port, gzip); if (port) m_StreamingDestinationsByPorts[port] = dest; - else // update default + else // update default m_StreamingDestination = dest; return dest; - } - + } + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination () { if (m_DatagramDestination == nullptr) m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis ()); - return m_DatagramDestination; + return m_DatagramDestination; } std::vector > ClientDestination::GetAllStreams () const @@ -944,12 +898,12 @@ namespace client { for (auto& it: m_StreamingDestination->GetStreams ()) ret.push_back (it.second); - } + } for (auto& it: m_StreamingDestinationsByPorts) for (auto& it1: it.second->GetStreams ()) ret.push_back (it1.second); return ret; - } + } void ClientDestination::PersistTemporaryKeys () { @@ -973,7 +927,7 @@ namespace client return; } LogPrint(eLogError, "Destinations: Can't save keys to ", path); - } + } void ClientDestination::CreateNewLeaseSet (std::vector > tunnels) { @@ -981,7 +935,7 @@ namespace client // sign Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); // TODO SetLeaseSet (leaseSet); - } + } void ClientDestination::CleanupDestination () { diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index 4e299322..ef7437fb 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -63,7 +63,6 @@ namespace client public std::enable_shared_from_this { typedef std::function leaseSet)> RequestComplete; - typedef std::function ReadyCallback; // leaseSet = nullptr means not found struct LeaseSetRequest { @@ -109,8 +108,6 @@ namespace client void ProcessDeliveryStatusMessage (std::shared_ptr msg); void SetLeaseSetUpdated (); - void AddReadyCallback(ReadyCallback cb); - protected: void SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet); @@ -134,8 +131,7 @@ namespace client void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete); bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request); void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest); - void HandleCleanupTimer (const boost::system::error_code& ecode); - void HandleReadyCheckTimer (const boost::system::error_code& ecode); + void HandleCleanupTimer (const boost::system::error_code& ecode); void CleanupRemoteLeaseSets (); private: @@ -156,9 +152,7 @@ namespace client std::set m_ExcludedFloodfills; // for publishing boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, - m_PublishDelayTimer, m_CleanupTimer, m_ReadyCheckTimer; - - std::vector m_ReadyCallbacks; + m_PublishDelayTimer, m_CleanupTimer; public: @@ -188,9 +182,9 @@ namespace client void Sign (const uint8_t * buf, int len, uint8_t * signature) const { m_Keys.Sign (buf, len, signature); }; // ref counter - int Acquire () { return ++m_RefCounter; }; + int Acquire () { return ++m_RefCounter; }; int Release () { return --m_RefCounter; }; - int GetRefCounter () const { return m_RefCounter; }; + int GetRefCounter () const { return m_RefCounter; }; // streaming std::shared_ptr CreateStreamingDestination (int port, bool gzip = true); // additional From 1ea6d2016d58ae841d183c21316a68df35cc5340 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 31 Aug 2017 12:08:22 -0400 Subject: [PATCH 30/81] add initial connection timeout for i2ptunnel --- libi2pd/Destination.cpp | 328 +++++++++++++++---------------- libi2pd_client/ClientContext.cpp | 25 ++- libi2pd_client/ClientContext.h | 1 + libi2pd_client/I2PService.cpp | 134 ++++++++++--- libi2pd_client/I2PService.h | 24 ++- libi2pd_client/I2PTunnel.cpp | 194 +++++++++--------- 6 files changed, 408 insertions(+), 298 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d45fdf47..b0e3365a 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -13,8 +13,8 @@ namespace i2p namespace client { LeaseSetDestination::LeaseSetDestination (bool isPublic, const std::map * params): - m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), - m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), + m_IsRunning (false), m_Thread (nullptr), m_IsPublic (isPublic), + m_PublishReplyToken (0), m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service), m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service) { int inLen = DEFAULT_INBOUND_TUNNEL_LENGTH; @@ -83,77 +83,77 @@ namespace client LeaseSetDestination::~LeaseSetDestination () { - if (m_IsRunning) + if (m_IsRunning) Stop (); if (m_Pool) - i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); + i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); for (auto& it: m_LeaseSetRequests) it.second->Complete (nullptr); - } + } void LeaseSetDestination::Run () { while (m_IsRunning) { try - { + { m_Service.run (); } catch (std::exception& ex) { LogPrint (eLogError, "Destination: runtime exception: ", ex.what ()); - } - } - } + } + } + } bool LeaseSetDestination::Start () - { + { if (!m_IsRunning) - { + { LoadTags (); m_IsRunning = true; m_Pool->SetLocalDestination (shared_from_this ()); - m_Pool->SetActive (true); + m_Pool->SetActive (true); m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT)); m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); m_Thread = new std::thread (std::bind (&LeaseSetDestination::Run, shared_from_this ())); - + return true; - } + } else return false; } - + bool LeaseSetDestination::Stop () - { + { if (m_IsRunning) - { + { m_CleanupTimer.cancel (); m_PublishConfirmationTimer.cancel (); - m_PublishVerificationTimer.cancel (); + m_PublishVerificationTimer.cancel (); m_IsRunning = false; if (m_Pool) - { + { m_Pool->SetLocalDestination (nullptr); i2p::tunnel::tunnels.StopTunnelPool (m_Pool); - } + } m_Service.stop (); if (m_Thread) - { - m_Thread->join (); + { + m_Thread->join (); delete m_Thread; m_Thread = 0; - } + } SaveTags (); CleanUp (); // GarlicDestination return true; - } + } else return false; - } - + } + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; @@ -164,7 +164,7 @@ namespace client remoteLS = it->second; } - if (remoteLS) + if (remoteLS) { if (!remoteLS->IsExpired ()) { @@ -193,9 +193,9 @@ namespace client m_RemoteLeaseSets.erase (ident); return nullptr; } - } + } else - { + { auto ls = i2p::data::netdb.FindLeaseSet (ident); if (ls && !ls->IsExpired ()) { @@ -203,7 +203,7 @@ namespace client std::lock_guard _lock(m_RemoteLeaseSetsMutex); m_RemoteLeaseSets[ident] = ls; return ls; - } + } } return nullptr; } @@ -215,11 +215,11 @@ namespace client UpdateLeaseSet (); std::lock_guard l(m_LeaseSetMutex); return m_LeaseSet; - } + } void LeaseSetDestination::SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet) { - { + { std::lock_guard l(m_LeaseSetMutex); m_LeaseSet.reset (newLeaseSet); } @@ -229,21 +229,21 @@ namespace client m_PublishVerificationTimer.cancel (); Publish (); } - } - + } + void LeaseSetDestination::UpdateLeaseSet () { - int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels - if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum + int numTunnels = m_Pool->GetNumInboundTunnels () + 2; // 2 backup tunnels + if (numTunnels > i2p::data::MAX_NUM_LEASES) numTunnels = i2p::data::MAX_NUM_LEASES; // 16 tunnels maximum CreateNewLeaseSet (m_Pool->GetInboundTunnels (numTunnels)); - } + } bool LeaseSetDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag) { struct { uint8_t k[32], t[32]; - } data; + } data; memcpy (data.k, key, 32); memcpy (data.t, tag, 32); auto s = shared_from_this (); @@ -256,42 +256,42 @@ namespace client void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); + m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg)); } void LeaseSetDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); + m_Service.post (std::bind (&LeaseSetDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); } void LeaseSetDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET]; switch (typeID) - { + { case eI2NPData: HandleDataMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; case eI2NPDeliveryStatus: // we assume tunnel tests non-encrypted HandleDeliveryStatusMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); - break; + break; case eI2NPDatabaseStore: HandleDatabaseStoreMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); break; case eI2NPDatabaseSearchReply: HandleDatabaseSearchReplyMessage (buf + I2NP_HEADER_SIZE, bufbe16toh (buf + I2NP_HEADER_SIZE_OFFSET)); - break; + break; default: i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); - } - } + } + } void LeaseSetDestination::HandleDatabaseStoreMessage (const uint8_t * buf, size_t len) { uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET); size_t offset = DATABASE_STORE_HEADER_SIZE; - if (replyToken) + if (replyToken) { LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore"); offset += 36; @@ -307,8 +307,8 @@ namespace client { leaseSet = it->second; if (leaseSet->IsNewer (buf + offset, len - offset)) - { - leaseSet->Update (buf + offset, len - offset); + { + leaseSet->Update (buf + offset, len - offset); if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) LogPrint (eLogDebug, "Destination: Remote LeaseSet updated"); else @@ -322,7 +322,7 @@ namespace client LogPrint (eLogDebug, "Destination: Remote LeaseSet is older. Not updated"); } else - { + { leaseSet = std::make_shared (buf + offset, len - offset); if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key) { @@ -339,18 +339,18 @@ namespace client LogPrint (eLogError, "Destination: New remote LeaseSet failed"); leaseSet = nullptr; } - } - } + } + } else LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped"); - + auto it1 = m_LeaseSetRequests.find (key); if (it1 != m_LeaseSetRequests.end ()) { it1->second->requestTimeoutTimer.cancel (); if (it1->second) it1->second->Complete (leaseSet); m_LeaseSetRequests.erase (it1); - } + } } void LeaseSetDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len) @@ -364,7 +364,7 @@ namespace client auto request = it->second; bool found = false; if (request->excluded.size () < MAX_NUM_FLOODFILLS_PER_REQUEST) - { + { for (int i = 0; i < num; i++) { i2p::data::IdentHash peerHash (buf + 33 + i*32); @@ -372,28 +372,28 @@ namespace client { LogPrint (eLogInfo, "Destination: Found new floodfill, request it"); // TODO: recheck this message i2p::data::netdb.RequestDestination (peerHash); - } + } } - + auto floodfill = i2p::data::netdb.GetClosestFloodfill (key, request->excluded); if (floodfill) { LogPrint (eLogInfo, "Destination: Requesting ", key.ToBase64 (), " at ", floodfill->GetIdentHash ().ToBase64 ()); if (SendLeaseSetRequest (key, floodfill, request)) found = true; - } - } + } + } if (!found) - { + { LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); request->Complete (nullptr); m_LeaseSetRequests.erase (key); - } - } - else + } + } + else LogPrint (eLogWarning, "Destination: Request for ", key.ToBase64 (), " not found"); - } - + } + void LeaseSetDestination::HandleDeliveryStatusMessage (std::shared_ptr msg) { uint32_t msgID = bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET); @@ -405,20 +405,20 @@ namespace client // schedule verification m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT)); m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); } else i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msg); - } + } void LeaseSetDestination::SetLeaseSetUpdated () - { + { UpdateLeaseSet (); } - + void LeaseSetDestination::Publish () - { - if (!m_LeaseSet || !m_Pool) + { + if (!m_LeaseSet || !m_Pool) { LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet"); return; @@ -435,9 +435,9 @@ namespace client m_PublishDelayTimer.cancel (); m_PublishDelayTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_MIN_INTERVAL)); m_PublishDelayTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishDelayTimer, - shared_from_this (), std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); return; - } + } auto outbound = m_Pool->GetNextOutboundTunnel (); if (!outbound) { @@ -450,28 +450,28 @@ namespace client LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); return; } - auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); + auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); if (!floodfill) { LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); m_ExcludedFloodfills.clear (); return; - } + } m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); + auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, - shared_from_this (), std::placeholders::_1)); - outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); + shared_from_this (), std::placeholders::_1)); + outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0, msg); m_LastSubmissionTime = ts; } void LeaseSetDestination::HandlePublishConfirmationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { if (m_PublishReplyToken) { LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again"); @@ -484,25 +484,25 @@ namespace client void LeaseSetDestination::HandlePublishVerificationTimer (const boost::system::error_code& ecode) { if (ecode != boost::asio::error::operation_aborted) - { + { auto s = shared_from_this (); - RequestLeaseSet (GetIdentHash (), + RequestLeaseSet (GetIdentHash (), // "this" added due to bug in gcc 4.7-4.8 [s,this](std::shared_ptr leaseSet) { - if (leaseSet) + if (leaseSet) { if (s->m_LeaseSet && *s->m_LeaseSet == *leaseSet) { // we got latest LeasetSet LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32()); s->m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_REGULAR_VERIFICATION_INTERNAL)); - s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); + s->m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer, s, std::placeholders::_1)); return; - } + } else LogPrint (eLogDebug, "Destination: LeaseSet is different than just published for ", GetIdentHash().ToBase32()); - } + } else LogPrint (eLogWarning, "Destination: couldn't find published LeaseSet for ", GetIdentHash().ToBase32()); // we have to publish again @@ -515,16 +515,16 @@ namespace client { if (ecode != boost::asio::error::operation_aborted) Publish (); - } - + } + bool LeaseSetDestination::RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete) { - if (!m_Pool || !IsReady ()) - { - if (requestComplete) + if (!m_Pool || !IsReady ()) + { + if (requestComplete) m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; - } + } m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), dest, requestComplete)); return true; } @@ -536,14 +536,14 @@ namespace client { auto it = s->m_LeaseSetRequests.find (dest); if (it != s->m_LeaseSetRequests.end ()) - { - auto requestComplete = it->second; + { + auto requestComplete = it->second; s->m_LeaseSetRequests.erase (it); if (notify && requestComplete) requestComplete->Complete (nullptr); - } - }); + } + }); } - + void LeaseSetDestination::RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete) { std::set excluded; @@ -564,28 +564,28 @@ namespace client m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); } - } + } else // duplicate { LogPrint (eLogInfo, "Destination: Request of LeaseSet ", dest.ToBase64 (), " is pending already"); if (ts > ret.first->second->requestTime + MAX_LEASESET_REQUEST_TIMEOUT) - { + { // something went wrong m_LeaseSetRequests.erase (ret.first); if (requestComplete) requestComplete (nullptr); } else if (requestComplete) ret.first->second->requestComplete.push_back (requestComplete); - } - } + } + } else - { + { LogPrint (eLogError, "Destination: Can't request LeaseSet, no floodfills found"); if (requestComplete) requestComplete (nullptr); - } - } - - bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, + } + } + + bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr nextFloodfill, std::shared_ptr request) { if (!request->replyTunnel || !request->replyTunnel->IsEstablished ()) @@ -594,36 +594,36 @@ namespace client if (!request->outboundTunnel || !request->outboundTunnel->IsEstablished ()) request->outboundTunnel = m_Pool->GetNextOutboundTunnel (); if (!request->outboundTunnel) LogPrint (eLogError, "Destination: Can't send LeaseSet request, no outbound tunnels found"); - + if (request->replyTunnel && request->outboundTunnel) - { + { request->excluded.insert (nextFloodfill->GetIdentHash ()); request->requestTimeoutTimer.cancel (); uint8_t replyKey[32], replyTag[32]; - RAND_bytes (replyKey, 32); // random session key + RAND_bytes (replyKey, 32); // random session key RAND_bytes (replyTag, 32); // random session tag AddSessionKey (replyKey, replyTag); auto msg = WrapMessage (nextFloodfill, - CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, request->replyTunnel, replyKey, replyTag)); request->outboundTunnel->SendTunnelDataMsg ( { - i2p::tunnel::TunnelMessageBlock - { + i2p::tunnel::TunnelMessageBlock + { i2p::tunnel::eDeliveryTypeRouter, nextFloodfill->GetIdentHash (), 0, msg } - }); + }); request->requestTimeoutTimer.expires_from_now (boost::posix_time::seconds(LEASESET_REQUEST_TIMEOUT)); request->requestTimeoutTimer.async_wait (std::bind (&LeaseSetDestination::HandleRequestTimoutTimer, shared_from_this (), std::placeholders::_1, dest)); - } + } else return false; return true; - } + } void LeaseSetDestination::HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest) { @@ -641,26 +641,26 @@ namespace client { // reset tunnels, because one them might fail it->second->outboundTunnel = nullptr; - it->second->replyTunnel = nullptr; + it->second->replyTunnel = nullptr; done = !SendLeaseSetRequest (dest, floodfill, it->second); } else done = true; } else - { + { LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds"); done = true; } - + if (done) { - auto requestComplete = it->second; + auto requestComplete = it->second; m_LeaseSetRequests.erase (it); if (requestComplete) requestComplete->Complete (nullptr); - } - } - } + } + } + } } void LeaseSetDestination::HandleCleanupTimer (const boost::system::error_code& ecode) @@ -674,7 +674,7 @@ namespace client m_CleanupTimer.async_wait (std::bind (&LeaseSetDestination::HandleCleanupTimer, shared_from_this (), std::placeholders::_1)); } - } + } void LeaseSetDestination::CleanupRemoteLeaseSets () { @@ -686,43 +686,43 @@ namespace client { LogPrint (eLogWarning, "Destination: Remote LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired"); it = m_RemoteLeaseSets.erase (it); - } - else + } + else ++it; } - } + } ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map * params): LeaseSetDestination (isPublic, params), m_Keys (keys), m_DatagramDestination (nullptr), m_RefCounter (0), m_ReadyChecker(GetService()) { - if (isPublic) + if (isPublic) PersistTemporaryKeys (); else i2p::crypto::GenerateElGamalKeyPair(m_EncryptionPrivateKey, m_EncryptionPublicKey); if (isPublic) LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created"); - } + } - ClientDestination::~ClientDestination () + ClientDestination::~ClientDestination () { - } - + } + bool ClientDestination::Start () { if (LeaseSetDestination::Start ()) - { + { m_StreamingDestination = std::make_shared (GetSharedFromThis ()); // TODO: - m_StreamingDestination->Start (); + m_StreamingDestination->Start (); for (auto& it: m_StreamingDestinationsByPorts) it.second->Start (); return true; - } + } else return false; - } - + } + bool ClientDestination::Stop () { if (LeaseSetDestination::Stop ()) @@ -732,21 +732,21 @@ namespace client //m_StreamingDestination->SetOwner (nullptr); m_StreamingDestination = nullptr; for (auto& it: m_StreamingDestinationsByPorts) - { + { it.second->Stop (); //it.second->SetOwner (nullptr); } m_StreamingDestinationsByPorts.clear (); if (m_DatagramDestination) - { + { delete m_DatagramDestination; m_DatagramDestination = nullptr; - } + } return true; } else return false; - } + } #ifdef I2LUA void ClientDestination::Ready(ReadyPromise & p) @@ -773,14 +773,14 @@ namespace client ScheduleCheckForReady(p); } #endif - + void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len) { uint32_t length = bufbe32toh (buf); buf += 4; // we assume I2CP payload uint16_t fromPort = bufbe16toh (buf + 4), // source - toPort = bufbe16toh (buf + 6); // destination + toPort = bufbe16toh (buf + 6); // destination switch (buf[9]) { case PROTOCOL_TYPE_STREAMING: @@ -804,14 +804,14 @@ namespace client LogPrint (eLogError, "Destination: Data: unexpected protocol ", buf[9]); } } - - void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) + + void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port) { - if (!streamRequestComplete) + if (!streamRequestComplete) { LogPrint (eLogError, "Destination: request callback is not specified in CreateStream"); return; - } + } auto leaseSet = FindLeaseSet (dest); if (leaseSet) streamRequestComplete(CreateStream (leaseSet, port)); @@ -837,18 +837,18 @@ namespace client return nullptr; } - std::shared_ptr ClientDestination::GetStreamingDestination (int port) const - { - if (port) + std::shared_ptr ClientDestination::GetStreamingDestination (int port) const + { + if (port) { auto it = m_StreamingDestinationsByPorts.find (port); if (it != m_StreamingDestinationsByPorts.end ()) return it->second; - } + } // if port is zero or not found, use default destination - return m_StreamingDestination; + return m_StreamingDestination; } - + void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor) { if (m_StreamingDestination) @@ -860,35 +860,35 @@ namespace client if (m_StreamingDestination) m_StreamingDestination->ResetAcceptor (); } - + bool ClientDestination::IsAcceptingStreams () const { if (m_StreamingDestination) return m_StreamingDestination->IsAcceptorSet (); return false; - } + } void ClientDestination::AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor) { if (m_StreamingDestination) m_StreamingDestination->AcceptOnce (acceptor); - } - + } + std::shared_ptr ClientDestination::CreateStreamingDestination (int port, bool gzip) { - auto dest = std::make_shared (GetSharedFromThis (), port, gzip); + auto dest = std::make_shared (GetSharedFromThis (), port, gzip); if (port) m_StreamingDestinationsByPorts[port] = dest; - else // update default + else // update default m_StreamingDestination = dest; return dest; - } - + } + i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination () { if (m_DatagramDestination == nullptr) m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis ()); - return m_DatagramDestination; + return m_DatagramDestination; } std::vector > ClientDestination::GetAllStreams () const @@ -898,12 +898,12 @@ namespace client { for (auto& it: m_StreamingDestination->GetStreams ()) ret.push_back (it.second); - } + } for (auto& it: m_StreamingDestinationsByPorts) for (auto& it1: it.second->GetStreams ()) ret.push_back (it1.second); return ret; - } + } void ClientDestination::PersistTemporaryKeys () { @@ -927,7 +927,7 @@ namespace client return; } LogPrint(eLogError, "Destinations: Can't save keys to ", path); - } + } void ClientDestination::CreateNewLeaseSet (std::vector > tunnels) { @@ -935,7 +935,7 @@ namespace client // sign Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); // TODO SetLeaseSet (leaseSet); - } + } void ClientDestination::CleanupDestination () { diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 4eea297e..08c164ae 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -48,7 +48,7 @@ namespace client std::shared_ptr localDestination; bool httproxy; i2p::config::GetOption("httpproxy.enabled", httproxy); - if (httproxy) + if (httproxy) { std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys); std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); @@ -68,12 +68,12 @@ namespace client else LogPrint(eLogError, "Clients: failed to load HTTP Proxy key"); } - try + try { m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination); m_HttpProxy->Start(); - } - catch (std::exception& e) + } + catch (std::exception& e) { LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what()); } @@ -253,7 +253,7 @@ namespace client void ClientContext::ReloadConfig () { - // TODO: handle config changes + // TODO: handle config changes /*std::string config; i2p::config::GetOption("conf", config); i2p::config::ParseConfig(config);*/ @@ -269,7 +269,7 @@ namespace client std::unique_lock l(m_DestinationsMutex); for (auto it = m_Destinations.begin (); it != m_Destinations.end ();) { - auto dest = it->second; + auto dest = it->second; if (dest->GetRefCounter () > 0) ++it; // skip else { @@ -551,6 +551,13 @@ namespace client clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); clientEndpoint = ((I2PClientTunnel*)clientTunnel)->GetLocalEndpoint (); } + uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); + if(timeout) + { + clientTunnel->SetConnectTimeout(timeout); + LogPrint(eLogInfo, "Clients: I2P Client tunnel connect timeout set to ", timeout); + } + auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr(clientTunnel))); if (ins.second) { @@ -657,7 +664,7 @@ namespace client } auto ins = m_ServerTunnels.insert (std::make_pair ( std::make_pair (localDestination->GetIdentHash (), inPort), - std::unique_ptr(serverTunnel))); + std::unique_ptr(serverTunnel))); if (ins.second) { serverTunnel->Start (); @@ -715,8 +722,8 @@ namespace client it = c.erase (it); } else - it++; - } + it++; + } } template diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 0eef1f79..f22c0817 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -36,6 +36,7 @@ namespace client const char I2P_CLIENT_TUNNEL_SIGNATURE_TYPE[] = "signaturetype"; const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels"; + const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout"; const char I2P_SERVER_TUNNEL_HOST[] = "host"; const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride"; const char I2P_SERVER_TUNNEL_PORT[] = "port"; diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 9348ec48..a90cf3d4 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -2,6 +2,7 @@ #include "Identity.h" #include "ClientContext.h" #include "I2PService.h" +#include namespace i2p { @@ -11,37 +12,101 @@ namespace client I2PService::I2PService (std::shared_ptr localDestination): m_LocalDestination (localDestination ? localDestination : - i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)), isUpdated (true) + i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)), + m_ReadyTimer(m_LocalDestination->GetService()), + m_ConnectTimeout(0), + isUpdated (true) { - m_LocalDestination->Acquire (); + m_LocalDestination->Acquire (); } - + I2PService::I2PService (i2p::data::SigningKeyType kt): m_LocalDestination (i2p::client::context.CreateNewLocalDestination (false, kt)), + m_ReadyTimer(m_LocalDestination->GetService()), + m_ConnectTimeout(0), isUpdated (true) { m_LocalDestination->Acquire (); } - - I2PService::~I2PService () - { - ClearHandlers (); - if (m_LocalDestination) m_LocalDestination->Release (); + + I2PService::~I2PService () + { + ClearHandlers (); + if (m_LocalDestination) m_LocalDestination->Release (); } void I2PService::ClearHandlers () { + if(m_ConnectTimeout) + m_ReadyTimer.cancel(); std::unique_lock l(m_HandlersMutex); for (auto it: m_Handlers) it->Terminate (); m_Handlers.clear(); } - + + void I2PService::SetConnectTimeout(uint32_t timeout) + { + if(timeout && !m_ConnectTimeout) + { + TriggerReadyCheckTimer(); + } + else if (m_ConnectTimeout && !timeout) + { + m_ReadyTimer.cancel(); + } + m_ConnectTimeout = timeout; + } + + void I2PService::AddReadyCallback(ReadyCallback cb) + { + uint32_t now = i2p::util::GetSecondsSinceEpoch(); + uint32_t tm = now + m_ConnectTimeout; + LogPrint(eLogDebug, "I2PService::AddReadyCallback() ", tm, " ", now); + m_ReadyCallbacks.push_back({cb, tm}); + } + + void I2PService::TriggerReadyCheckTimer() + { + m_ReadyTimer.expires_from_now(boost::posix_time::seconds (1)); + m_ReadyTimer.async_wait(std::bind(&I2PService::HandleReadyCheckTimer, this, std::placeholders::_1)); + } + + void I2PService::HandleReadyCheckTimer(const boost::system::error_code &ec) + { + if(ec || m_LocalDestination->IsReady()) + { + for(auto & itr : m_ReadyCallbacks) + itr.first(ec); + m_ReadyCallbacks.clear(); + } + else if(!m_LocalDestination->IsReady()) + { + // expire timed out requests + uint32_t now = i2p::util::GetSecondsSinceEpoch (); + auto itr = m_ReadyCallbacks.begin(); + while(itr != m_ReadyCallbacks.end()) + { + if(itr->second >= now) + { + itr->first(boost::asio::error::timed_out); + itr = m_ReadyCallbacks.erase(itr); + } + else + ++itr; + } + } + if(!ec) + TriggerReadyCheckTimer(); + } + void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) { assert(streamRequestComplete); i2p::data::IdentHash identHash; if (i2p::client::context.GetAddressBook ().GetIdentHash (dest, identHash)) - m_LocalDestination->CreateStream (streamRequestComplete, identHash, port); + { + CreateStream(streamRequestComplete, identHash, port); + } else { LogPrint (eLogWarning, "I2PService: Remote destination not found: ", dest); @@ -49,6 +114,29 @@ namespace client } } + void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash & identHash, int port) + { + if(m_ConnectTimeout) + { + if(m_LocalDestination->IsReady()) + m_LocalDestination->CreateStream (streamRequestComplete, identHash, port); + else + { + AddReadyCallback([this, streamRequestComplete, identHash, port] (const boost::system::error_code & ec) { + if(ec) + { + LogPrint(eLogWarning, "I2PService::CeateStream() ", ec.message()); + streamRequestComplete(nullptr); + } + else + this->m_LocalDestination->CreateStream(streamRequestComplete, identHash, port); + }); + } + } + else + m_LocalDestination->CreateStream(streamRequestComplete, identHash, port); + } + TCPIPPipe::TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) : I2PServiceHandler(owner), m_up(upstream), m_down(downstream) { boost::asio::socket_base::receive_buffer_size option(TCP_IP_PIPE_BUFFER_SIZE); @@ -60,7 +148,7 @@ namespace client { Terminate(); } - + void TCPIPPipe::Start() { AsyncReceiveUpstream(); @@ -84,7 +172,7 @@ namespace client } Done(shared_from_this()); } - + void TCPIPPipe::AsyncReceiveUpstream() { if (m_up) { @@ -132,12 +220,12 @@ namespace client shared_from_this(), std::placeholders::_1) ); - } else { + } else { LogPrint(eLogError, "TCPIPPipe: downstream write: no socket"); } } - - + + void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { LogPrint(eLogDebug, "TCPIPPipe: downstream: ", (int) bytes_transfered, " bytes received"); @@ -162,7 +250,7 @@ namespace client AsyncReceiveUpstream(); } } - + void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) { if (ecode) { LogPrint(eLogError, "TCPIPPipe: upstream write error:" , ecode.message()); @@ -172,7 +260,7 @@ namespace client AsyncReceiveDownstream(); } } - + void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { LogPrint(eLogDebug, "TCPIPPipe: upstream ", (int)bytes_transfered, " bytes received"); @@ -187,7 +275,7 @@ namespace client DownstreamWrite(bytes_transfered); } } - + void TCPIPAcceptor::Start () { m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint)); @@ -198,10 +286,10 @@ namespace client void TCPIPAcceptor::Stop () { if (m_Acceptor) - { + { m_Acceptor->close(); m_Acceptor.reset (nullptr); - } + } m_Timer.cancel (); ClearHandlers(); } @@ -219,12 +307,12 @@ namespace client { LogPrint(eLogDebug, "I2PService: ", GetName(), " accepted"); auto handler = CreateHandler(socket); - if (handler) + if (handler) { AddHandler(handler); handler->Handle(); - } - else + } + else socket->close(); Accept(); } diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index cf0cfd98..b708125f 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -14,8 +14,10 @@ namespace i2p namespace client { class I2PServiceHandler; - class I2PService + class I2PService : std::enable_shared_from_this { + public: + typedef std::function ReadyCallback; public: I2PService (std::shared_ptr localDestination = nullptr); I2PService (i2p::data::SigningKeyType kt); @@ -33,25 +35,37 @@ namespace client } void ClearHandlers (); + void SetConnectTimeout(uint32_t timeout); + + void AddReadyCallback(ReadyCallback cb); + inline std::shared_ptr GetLocalDestination () { return m_LocalDestination; } inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } inline void SetLocalDestination (std::shared_ptr dest) { m_LocalDestination = dest; } void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0); - + void CreateStream(StreamRequestComplete complete, const i2p::data::IdentHash & ident, int port); inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); } virtual void Start () = 0; virtual void Stop () = 0; virtual const char* GetName() { return "Generic I2P Service"; } + + private: + void TriggerReadyCheckTimer(); + void HandleReadyCheckTimer(const boost::system::error_code & ec); + private: std::shared_ptr m_LocalDestination; std::unordered_set > m_Handlers; std::mutex m_HandlersMutex; + std::vector > m_ReadyCallbacks; + boost::asio::deadline_timer m_ReadyTimer; + uint32_t m_ConnectTimeout; public: - bool isUpdated; // transient, used during reload only + bool isUpdated; // transient, used during reload only }; /*Simple interface for I2PHandlers, allows detection of finalization amongst other things */ @@ -64,7 +78,7 @@ namespace client virtual void Handle() {}; //Start handling the socket void Terminate () { Kill (); }; - + protected: // Call when terminating or handing over to avoid race conditions inline bool Kill () { return m_Dead.exchange(true); } @@ -102,7 +116,7 @@ namespace client uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE]; std::shared_ptr m_up, m_down; }; - + /* TODO: support IPv6 too */ //This is a service that listens for connections on the IP network and interacts with I2P class TCPIPAcceptor: public I2PService diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 71b09e1a..8d559aee 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -14,19 +14,19 @@ namespace client static void I2PTunnelSetSocketOptions(std::shared_ptr socket) { if (socket && socket->is_open()) - { + { boost::asio::socket_base::receive_buffer_size option(I2P_TUNNEL_CONNECTION_BUFFER_SIZE); socket->set_option(option); } } - + I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, - std::shared_ptr leaseSet, int port): + std::shared_ptr leaseSet, int port): I2PServiceHandler(owner), m_Socket (socket), m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true) { m_Stream = GetOwner()->GetLocalDestination ()->CreateStream (leaseSet, port); - } + } I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream): @@ -44,15 +44,15 @@ namespace client I2PTunnelConnection::~I2PTunnelConnection () { - } - + } + void I2PTunnelConnection::I2PConnect (const uint8_t * msg, size_t len) { if (m_Stream) { if (msg) m_Stream->Send (msg, len); // connect and send - else + else m_Stream->Send (m_Buffer, 0); // connect } StreamReceive (); @@ -68,11 +68,11 @@ namespace client boost::asio::ip::address ourIP = boost::asio::ip::address_v4 (bytes); return ourIP; } - + static void MapToLoopback(const std::shared_ptr & sock, const i2p::data::IdentHash & addr) { - // bind to 127.x.x.x address + // bind to 127.x.x.x address // where x.x.x are first three bytes from ident auto ourIP = GetLoopbackAddressFor(addr); sock->bind (boost::asio::ip::tcp::endpoint (ourIP, 0)); @@ -82,7 +82,7 @@ namespace client void I2PTunnelConnection::Connect (bool isUniqueLocal) { I2PTunnelSetSocketOptions(m_Socket); - if (m_Socket) + if (m_Socket) { #ifdef __linux__ if (isUniqueLocal && m_RemoteEndpoint.address ().is_v4 () && @@ -96,8 +96,8 @@ namespace client m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect, shared_from_this (), std::placeholders::_1)); } - } - + } + void I2PTunnelConnection::Terminate () { if (Kill()) return; @@ -105,21 +105,21 @@ namespace client { m_Stream->Close (); m_Stream.reset (); - } + } boost::system::error_code ec; m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); // avoid RST m_Socket->close (); Done(shared_from_this ()); - } + } void I2PTunnelConnection::Receive () { - m_Socket->async_read_some (boost::asio::buffer(m_Buffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE), - std::bind(&I2PTunnelConnection::HandleReceived, shared_from_this (), + m_Socket->async_read_some (boost::asio::buffer(m_Buffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE), + std::bind(&I2PTunnelConnection::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); - } - + } + void I2PTunnelConnection::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) @@ -131,9 +131,9 @@ namespace client } } else - { + { if (m_Stream) - { + { auto s = shared_from_this (); m_Stream->AsyncSend (m_Buffer, bytes_transferred, [s](const boost::system::error_code& ecode) @@ -143,9 +143,9 @@ namespace client else s->Terminate (); }); - } + } } - } + } void I2PTunnelConnection::HandleWrite (const boost::system::error_code& ecode) { @@ -165,12 +165,12 @@ namespace client { if (m_Stream->GetStatus () == i2p::stream::eStreamStatusNew || m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular - { + { m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE), std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (), std::placeholders::_1, std::placeholders::_2), I2P_TUNNEL_CONNECTION_MAX_IDLE); - } + } else // closed by peer { // get remaning data @@ -178,10 +178,10 @@ namespace client if (len > 0) // still some data Write (m_StreamBuffer, len); else // no more data - Terminate (); - } - } - } + Terminate (); + } + } + } void I2PTunnelConnection::HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) { @@ -231,8 +231,8 @@ namespace client memcpy (m_StreamBuffer, dest.c_str (), dest.size ()); } HandleStreamReceive (boost::system::error_code (), dest.size ()); - } - Receive (); + } + Receive (); } } @@ -253,20 +253,20 @@ namespace client { if (line == "\r") endOfHeader = true; else - { + { if (!m_ConnectionSent && !line.compare(0, 10, "Connection")) - { + { m_OutHeader << "Connection: close\r\n"; m_ConnectionSent = true; - } + } else if (!m_ProxyConnectionSent && !line.compare(0, 16, "Proxy-Connection")) - { + { m_OutHeader << "Proxy-Connection: close\r\n"; m_ProxyConnectionSent = true; - } + } else m_OutHeader << line << "\n"; - } + } } else break; @@ -283,10 +283,10 @@ namespace client I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); } } - } - + } + I2PServerTunnelConnectionHTTP::I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, - std::shared_ptr socket, + std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host): I2PTunnelConnection (owner, stream, socket, target), m_Host (host), m_HeaderSent (false), m_From (stream->GetRemoteIdentity ()) { @@ -297,7 +297,7 @@ namespace client if (m_HeaderSent) I2PTunnelConnection::Write (buf, len); else - { + { m_InHeader.clear (); m_InHeader.write ((const char *)buf, len); std::string line; @@ -309,12 +309,12 @@ namespace client { if (line == "\r") endOfHeader = true; else - { + { if (m_Host.length () > 0 && line.find ("Host:") != std::string::npos) m_OutHeader << "Host: " << m_Host << "\r\n"; // override host else m_OutHeader << line << "\n"; - } + } } else break; @@ -335,13 +335,13 @@ namespace client m_HeaderSent = true; I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); } - } + } } I2PTunnelConnectionIRC::I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, - std::shared_ptr socket, + std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass): - I2PTunnelConnection (owner, stream, socket, target), m_From (stream->GetRemoteIdentity ()), + I2PTunnelConnection (owner, stream, socket, target), m_From (stream->GetRemoteIdentity ()), m_NeedsWebIrc (webircpass.length() ? true : false), m_WebircPass (webircpass) { } @@ -349,7 +349,7 @@ namespace client void I2PTunnelConnectionIRC::Write (const uint8_t * buf, size_t len) { m_OutPacket.str (""); - if (m_NeedsWebIrc) + if (m_NeedsWebIrc) { m_NeedsWebIrc = false; m_OutPacket << "WEBIRC " << m_WebircPass << " cgiirc " << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()) << " " << GetSocket ()->local_endpoint ().address () << std::endl; @@ -357,12 +357,12 @@ namespace client m_InPacket.clear (); m_InPacket.write ((const char *)buf, len); - + while (!m_InPacket.eof () && !m_InPacket.fail ()) { std::string line; std::getline (m_InPacket, line); - if (line.length () == 0 && m_InPacket.eof ()) + if (line.length () == 0 && m_InPacket.eof ()) m_InPacket.str (""); auto pos = line.find ("USER"); if (!pos) // start of line @@ -375,7 +375,7 @@ namespace client m_OutPacket << line.substr (0, pos); m_OutPacket << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()); m_OutPacket << line.substr (nextpos) << '\n'; - } + } else m_OutPacket << line << '\n'; } @@ -389,7 +389,7 @@ namespace client public: I2PClientTunnelHandler (I2PClientTunnel * parent, i2p::data::IdentHash destination, int destinationPort, std::shared_ptr socket): - I2PServiceHandler(parent), m_DestinationIdentHash(destination), + I2PServiceHandler(parent), m_DestinationIdentHash(destination), m_DestinationPort (destinationPort), m_Socket(socket) {}; void Handle(); void Terminate(); @@ -402,8 +402,8 @@ namespace client void I2PClientTunnelHandler::Handle() { - GetOwner()->GetLocalDestination ()->CreateStream ( - std::bind (&I2PClientTunnelHandler::HandleStreamRequestComplete, shared_from_this(), std::placeholders::_1), + GetOwner()->CreateStream ( + std::bind (&I2PClientTunnelHandler::HandleStreamRequestComplete, shared_from_this(), std::placeholders::_1), m_DestinationIdentHash, m_DestinationPort); } @@ -436,12 +436,12 @@ namespace client Done(shared_from_this()); } - I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, - const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): - TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), - m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort) + I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, + const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): + TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), + m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort) { - } + } void I2PClientTunnel::Start () { @@ -480,8 +480,8 @@ namespace client return nullptr; } - I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, int inport, bool gzip): + I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, + int port, std::shared_ptr localDestination, int inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) { m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip); @@ -489,10 +489,10 @@ namespace client void I2PServerTunnel::Start () { - m_Endpoint.port (m_Port); + m_Endpoint.port (m_Port); boost::system::error_code ec; auto addr = boost::asio::ip::address::from_string (m_Address, ec); - if (!ec) + if (!ec) { m_Endpoint.address (addr); Accept (); @@ -500,27 +500,27 @@ namespace client else { auto resolver = std::make_shared(GetService ()); - resolver->async_resolve (boost::asio::ip::tcp::resolver::query (m_Address, ""), - std::bind (&I2PServerTunnel::HandleResolve, this, + resolver->async_resolve (boost::asio::ip::tcp::resolver::query (m_Address, ""), + std::bind (&I2PServerTunnel::HandleResolve, this, std::placeholders::_1, std::placeholders::_2, resolver)); - } + } } void I2PServerTunnel::Stop () { ClearHandlers (); - } + } - void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, + void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, std::shared_ptr resolver) - { + { if (!ecode) - { + { auto addr = (*it).endpoint ().address (); LogPrint (eLogInfo, "I2PTunnel: server tunnel ", (*it).host_name (), " has been resolved to ", addr); m_Endpoint.address (addr); - Accept (); - } + Accept (); + } else LogPrint (eLogError, "I2PTunnel: Unable to resolve server tunnel address: ", ecode.message ()); } @@ -528,7 +528,7 @@ namespace client void I2PServerTunnel::SetAccessList (const std::set& accessList) { m_AccessList = accessList; - m_IsAccessList = true; + m_IsAccessList = true; } void I2PServerTunnel::Accept () @@ -536,7 +536,7 @@ namespace client if (m_PortDestination) m_PortDestination->SetAcceptor (std::bind (&I2PServerTunnel::HandleAccept, this, std::placeholders::_1)); - auto localDestination = GetLocalDestination (); + auto localDestination = GetLocalDestination (); if (localDestination) { if (!localDestination->IsAcceptingStreams ()) // set it as default if not set yet @@ -549,7 +549,7 @@ namespace client void I2PServerTunnel::HandleAccept (std::shared_ptr stream) { if (stream) - { + { if (m_IsAccessList) { if (!m_AccessList.count (stream->GetRemoteIdentity ()->GetIdentHash ())) @@ -563,31 +563,31 @@ namespace client auto conn = CreateI2PConnection (stream); AddHandler (conn); conn->Connect (m_IsUniqueLocal); - } + } } std::shared_ptr I2PServerTunnel::CreateI2PConnection (std::shared_ptr stream) { return std::make_shared (this, stream, std::make_shared (GetService ()), GetEndpoint ()); - + } - I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, + I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address, + int port, std::shared_ptr localDestination, const std::string& host, int inport, bool gzip): - I2PServerTunnel (name, address, port, localDestination, inport, gzip), + I2PServerTunnel (name, address, port, localDestination, inport, gzip), m_Host (host) { } std::shared_ptr I2PServerTunnelHTTP::CreateI2PConnection (std::shared_ptr stream) { - return std::make_shared (this, stream, + return std::make_shared (this, stream, std::make_shared (GetService ()), GetEndpoint (), m_Host); } - I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, + I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address, + int port, std::shared_ptr localDestination, const std::string& webircpass, int inport, bool gzip): I2PServerTunnel (name, address, port, localDestination, inport, gzip), m_WebircPass (webircpass) @@ -631,7 +631,7 @@ namespace client m_Sessions.erase(port); } } - + UDPSessionPtr I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort) { auto ih = from.GetIdentHash(); @@ -646,12 +646,12 @@ namespace client } boost::asio::ip::address addr; /** create new udp session */ - if(m_IsUniqueLocal && m_LocalAddress.is_loopback()) + if(m_IsUniqueLocal && m_LocalAddress.is_loopback()) { auto ident = from.GetIdentHash(); addr = GetLoopbackAddressFor(ident); - } - else + } + else addr = m_LocalAddress; boost::asio::ip::udp::endpoint ep(addr, 0); m_Sessions.push_back(std::make_shared(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort)); @@ -680,7 +680,7 @@ namespace client IPSocket.async_receive_from(boost::asio::buffer(m_Buffer, I2P_UDP_MAX_MTU), FromEndpoint, std::bind(&UDPSession::HandleReceived, this, std::placeholders::_1, std::placeholders::_2)); } - + void UDPSession::HandleReceived(const boost::system::error_code & ecode, std::size_t len) { if(!ecode) @@ -694,8 +694,8 @@ namespace client } } - - + + I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) : m_IsUniqueLocal(true), @@ -713,7 +713,7 @@ namespace client { auto dgram = m_LocalDest->GetDatagramDestination(); if (dgram) dgram->ResetReceiver(); - + LogPrint(eLogInfo, "UDPServer: done"); } @@ -742,7 +742,7 @@ namespace client } return sessions; } - + I2PUDPClientTunnel::I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest, boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr localDestination, @@ -764,8 +764,8 @@ namespace client std::placeholders::_5)); } - - + + void I2PUDPClientTunnel::Start() { m_LocalDest->Start(); if (m_ResolveThread == nullptr) @@ -803,14 +803,14 @@ namespace client m_Sessions[remotePort].second = i2p::util::GetMillisecondsSinceEpoch(); RecvFromLocal(); } - + std::vector > I2PUDPClientTunnel::GetSessions() { // TODO: implement std::vector > infos; return infos; } - + void I2PUDPClientTunnel::TryResolving() { LogPrint(eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest); i2p::data::IdentHash * h = new i2p::data::IdentHash; @@ -846,11 +846,11 @@ namespace client } } else - LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); + LogPrint(eLogWarning, "UDP Client: not tracking udp session using port ", (int) toPort); } else LogPrint(eLogWarning, "UDP Client: unwarrented traffic from ", from.GetIdentHash().ToBase32()); - + } I2PUDPClientTunnel::~I2PUDPClientTunnel() { @@ -858,7 +858,7 @@ namespace client if (dgram) dgram->ResetReceiver(); m_Sessions.clear(); - + if(m_LocalSocket.is_open()) m_LocalSocket.close(); From b0a6c9fa534a0cbcda1287af787e7b787451752a Mon Sep 17 00:00:00 2001 From: Markovskij Date: Sun, 3 Sep 2017 15:55:51 +0300 Subject: [PATCH 31/81] Make tunnels.conf more readable --- qt/i2pd_qt/TunnelConfig.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index 0de17486..d282f23c 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -6,12 +6,19 @@ void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { } void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { - out << "inbound.length=" << i2cpParameters.getInbound_length().toStdString() << "\n" - << "outbound.length=" << i2cpParameters.getOutbound_length().toStdString() << "\n" - << "inbound.quantity=" << i2cpParameters.getInbound_quantity().toStdString() << "\n" - << "outbound.quantity=" << i2cpParameters.getOutbound_quantity().toStdString() << "\n" - << "crypto.tagsToSend=" << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n" - << "explicitPeers=" << i2cpParameters.getExplicitPeers().toStdString() << "\n\n"; + if (i2cpParameters.getInbound_length().toUShort() != 3) + out << "inbound.length=" << i2cpParameters.getInbound_length().toStdString() << "\n"; + if (i2cpParameters.getOutbound_length().toUShort() != 3) + out << "outbound.length=" << i2cpParameters.getOutbound_length().toStdString() << "\n"; + if (i2cpParameters.getInbound_quantity().toUShort() != 5) + out << "inbound.quantity=" << i2cpParameters.getInbound_quantity().toStdString() << "\n"; + if (i2cpParameters.getOutbound_quantity().toUShort() != 5) + out << "outbound.quantity=" << i2cpParameters.getOutbound_quantity().toStdString() << "\n"; + if (i2cpParameters.getCrypto_tagsToSend().toUShort() != 40) + out << "crypto.tagsToSend=" << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; + if (!i2cpParameters.getExplicitPeers().isEmpty()) + out << "explicitPeers=" << i2cpParameters.getExplicitPeers().toStdString() << "\n"; + out << "\n"; } void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { From b2d1962b81bdb850f9659def60188977314e7c47 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 3 Sep 2017 09:46:55 -0400 Subject: [PATCH 32/81] add http connect to http proxy (untested) --- libi2pd_client/HTTPProxy.cpp | 164 ++++++++++++++++++++++++----------- 1 file changed, 114 insertions(+), 50 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 5056b737..42014467 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -67,17 +67,19 @@ namespace proxy { void ForwardToUpstreamProxy(); void HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec); void HandleUpstreamSocksProxyConnect(const boost::system::error_code & ec); - + void HTTPConnect(const std::string & host, uint16_t port); + void HandleHTTPConnectStreamRequestComplete(std::shared_ptr stream); + void HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transfered); void HandleSocksProxyReply(const boost::system::error_code & ec, std::size_t bytes_transfered); - + typedef std::function ProxyResolvedHandler; - + void HandleUpstreamProxyResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr, ProxyResolvedHandler handler); void SocksProxySuccess(); void HandoverToUpstreamProxy(); - + uint8_t m_recv_chunk[8192]; std::string m_recv_buf; // from client std::string m_send_buf; // to upstream @@ -116,7 +118,7 @@ namespace proxy { void HTTPReqHandler::Terminate() { if (Kill()) return; - if (m_sock) + if (m_sock) { LogPrint(eLogDebug, "HTTPProxy: close sock"); m_sock->close(); @@ -203,11 +205,11 @@ namespace proxy { req.RemoveHeader("Referer"); req.RemoveHeader("Via"); req.RemoveHeader("From"); - req.RemoveHeader("Forwarded"); + req.RemoveHeader("Forwarded"); req.RemoveHeader("Accept", "Accept-Encoding"); // Accept*, but Accept-Encoding /* drop proxy-disclosing headers */ req.RemoveHeader("X-Forwarded"); - req.RemoveHeader("Proxy-"); // Proxy-* + req.RemoveHeader("Proxy-"); // Proxy-* /* replace headers */ req.UpdateHeader("User-Agent", "MYOB/6.66 (AN/ON)"); /* add headers */ @@ -239,14 +241,14 @@ namespace proxy { LogPrint(eLogDebug, "HTTPProxy: requested: ", m_ClientRequest.uri); m_RequestURL.parse(m_ClientRequest.uri); - if (ExtractAddressHelper(m_RequestURL, b64)) + if (ExtractAddressHelper(m_RequestURL, b64)) { bool addresshelper; i2p::config::GetOption("httpproxy.addresshelper", addresshelper); if (!addresshelper) { LogPrint(eLogWarning, "HTTPProxy: addresshelper disabled"); GenericProxyError("Invalid request", "adddresshelper is not supported"); - return true; + return true; } i2p::client::context.GetAddressBook ().InsertAddress (m_RequestURL.host, b64); LogPrint (eLogInfo, "HTTPProxy: added b64 from addresshelper for ", m_RequestURL.host); @@ -257,43 +259,63 @@ namespace proxy { GenericProxyInfo("Addresshelper found", ss.str().c_str()); return true; /* request processed */ } - - SanitizeHTTPRequest(m_ClientRequest); - - std::string dest_host = m_RequestURL.host; - uint16_t dest_port = m_RequestURL.port; - /* always set port, even if missing in request */ - if (!dest_port) - dest_port = (m_RequestURL.schema == "https") ? 443 : 80; - /* detect dest_host, set proper 'Host' header in upstream request */ - if (dest_host != "") + std::string dest_host; + uint16_t dest_port; + bool useConnect = false; + if(m_ClientRequest.method == "CONNECT") { - /* absolute url, replace 'Host' header */ - std::string h = dest_host; - if (dest_port != 0 && dest_port != 80) - h += ":" + std::to_string(dest_port); - m_ClientRequest.UpdateHeader("Host", h); - } - else - { - auto h = m_ClientRequest.GetHeader ("Host"); - if (h.length () > 0) + std::string uri(m_ClientRequest.uri); + auto pos = uri.find(":"); + if(pos == std::string::npos || pos == uri.size() - 1) { - /* relative url and 'Host' header provided. transparent proxy mode? */ - i2p::http::URL u; - std::string t = "http://" + h; - u.parse(t); - dest_host = u.host; - dest_port = u.port; - } - else - { - /* relative url and missing 'Host' header */ - GenericProxyError("Invalid request", "Can't detect destination host from request"); + GenericProxyError("Invalid Request", "invalid request uri"); return true; } - } + else + { + useConnect = true; + dest_port = std::stoi(uri.substr(pos+1)); + dest_host = uri.substr(0, pos); + } + } + else + { + SanitizeHTTPRequest(m_ClientRequest); + dest_host = m_RequestURL.host; + dest_port = m_RequestURL.port; + /* always set port, even if missing in request */ + if (!dest_port) + dest_port = (m_RequestURL.schema == "https") ? 443 : 80; + /* detect dest_host, set proper 'Host' header in upstream request */ + if (dest_host != "") + { + /* absolute url, replace 'Host' header */ + std::string h = dest_host; + if (dest_port != 0 && dest_port != 80) + h += ":" + std::to_string(dest_port); + m_ClientRequest.UpdateHeader("Host", h); + } + else + { + auto h = m_ClientRequest.GetHeader ("Host"); + if (h.length () > 0) + { + /* relative url and 'Host' header provided. transparent proxy mode? */ + i2p::http::URL u; + std::string t = "http://" + h; + u.parse(t); + dest_host = u.host; + dest_port = u.port; + } + else + { + /* relative url and missing 'Host' header */ + GenericProxyError("Invalid request", "Can't detect destination host from request"); + return true; + } + } + } /* check dest_host really exists and inside I2P network */ i2p::data::IdentHash identHash; if (str_rmatch(dest_host, ".i2p")) { @@ -316,6 +338,11 @@ namespace proxy { } return true; } + if(useConnect) + { + HTTPConnect(dest_host, dest_port); + return true; + } /* make relative url */ m_RequestURL.schema = ""; @@ -347,7 +374,7 @@ namespace proxy { m_ClientRequest.write(m_ClientRequestBuffer); m_ClientRequestBuffer << m_recv_buf.substr(m_req_len); - + // assume http if empty schema if (m_ProxyURL.schema == "" || m_ProxyURL.schema == "http") { // handle upstream http proxy @@ -372,7 +399,7 @@ namespace proxy { void HTTPReqHandler::HandleUpstreamProxyResolved(const boost::system::error_code & ec, boost::asio::ip::tcp::resolver::iterator it, ProxyResolvedHandler handler) { if(ec) GenericProxyError("cannot resolve upstream proxy", ec.message().c_str()); - else handler(*it); + else handler(*it); } void HTTPReqHandler::HandleUpstreamSocksProxyConnect(const boost::system::error_code & ec) @@ -426,7 +453,44 @@ namespace proxy { connection->Start(); Terminate(); } - + + void HTTPReqHandler::HTTPConnect(const std::string & host, uint16_t port) + { + std::string hostname(host); + if(str_rmatch(hostname, ".i2p")) + GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleHTTPConnectStreamRequestComplete, + shared_from_this(), std::placeholders::_1), host, port); + else + ForwardToUpstreamProxy(); + } + + void HTTPReqHandler::HandleHTTPConnectStreamRequestComplete(std::shared_ptr stream) + { + if(stream) + { + m_ClientResponse.code = 101; + m_ClientResponse.status = "Switching Protocols"; + m_send_buf = m_ClientResponse.to_string(); + boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) { + if(ec) + { + LogPrint(eLogError, "HTTPProxy: failed to send reply: ", ec.message()); + } + else + { + auto connection = std::make_shared(GetOwner(), m_sock, stream); + GetOwner()->AddHandler(connection); + connection->I2PConnect(); + } + Done(shared_from_this()); + }); + } + else + { + GenericProxyError("CONNECT error", "Failed to Connect"); + } + } + void HTTPReqHandler::SocksProxySuccess() { if(m_ClientRequest.method == "CONNECT") { @@ -445,7 +509,7 @@ namespace proxy { }); } } - + void HTTPReqHandler::HandleSocksProxyReply(const boost::system::error_code & ec, std::size_t bytes_transferred) { if(!ec) @@ -463,7 +527,7 @@ namespace proxy { } else GenericProxyError("No Reply From socks proxy", ec.message().c_str()); } - + void HTTPReqHandler::HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec) { if(!ec) { @@ -471,12 +535,12 @@ namespace proxy { GenericProxyError("cannot connect", "http out proxy not implemented"); } else GenericProxyError("cannot connect to upstream http proxy", ec.message().c_str()); } - + /* will be called after some data received from client */ void HTTPReqHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len) { LogPrint(eLogDebug, "HTTPProxy: sock recv: ", len, " bytes, recv buf: ", m_recv_buf.length(), ", send buf: ", m_send_buf.length()); - if(ecode) + if(ecode) { LogPrint(eLogWarning, "HTTPProxy: sock recv got error: ", ecode); Terminate(); @@ -515,10 +579,10 @@ namespace proxy { } HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination): - TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) + TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) { } - + std::shared_ptr HTTPProxy::CreateHandler(std::shared_ptr socket) { return std::make_shared (this, socket); From d6f907a05beec157f895fdfe8e166d06f9841745 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 3 Sep 2017 11:13:43 -0400 Subject: [PATCH 33/81] make it work --- libi2pd_client/HTTPProxy.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 42014467..526e779e 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -456,6 +456,7 @@ namespace proxy { void HTTPReqHandler::HTTPConnect(const std::string & host, uint16_t port) { + LogPrint(eLogDebug, "HTTPProxy: CONNECT ",host, ":", port); std::string hostname(host); if(str_rmatch(hostname, ".i2p")) GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleHTTPConnectStreamRequestComplete, @@ -468,22 +469,15 @@ namespace proxy { { if(stream) { - m_ClientResponse.code = 101; - m_ClientResponse.status = "Switching Protocols"; + m_ClientResponse.code = 200; + m_ClientResponse.status = "OK"; m_send_buf = m_ClientResponse.to_string(); - boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) { - if(ec) - { - LogPrint(eLogError, "HTTPProxy: failed to send reply: ", ec.message()); - } - else - { - auto connection = std::make_shared(GetOwner(), m_sock, stream); - GetOwner()->AddHandler(connection); - connection->I2PConnect(); - } - Done(shared_from_this()); - }); + m_sock->send(boost::asio::buffer(m_send_buf)); + auto connection = std::make_shared(GetOwner(), m_sock, stream); + GetOwner()->AddHandler(connection); + connection->I2PConnect(); + m_sock = nullptr; + Terminate(); } else { From a549ebc25fc84387a51fc60c352197ec28460b2f Mon Sep 17 00:00:00 2001 From: Markovskij Date: Mon, 4 Sep 2017 07:23:59 +0300 Subject: [PATCH 34/81] Add constants --- qt/i2pd_qt/TunnelConfig.cpp | 28 +++++++++++++++++----------- qt/i2pd_qt/TunnelConfig.h | 1 + 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index d282f23c..8cf86d14 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -6,18 +6,24 @@ void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { } void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { - if (i2cpParameters.getInbound_length().toUShort() != 3) - out << "inbound.length=" << i2cpParameters.getInbound_length().toStdString() << "\n"; - if (i2cpParameters.getOutbound_length().toUShort() != 3) - out << "outbound.length=" << i2cpParameters.getOutbound_length().toStdString() << "\n"; - if (i2cpParameters.getInbound_quantity().toUShort() != 5) - out << "inbound.quantity=" << i2cpParameters.getInbound_quantity().toStdString() << "\n"; - if (i2cpParameters.getOutbound_quantity().toUShort() != 5) - out << "outbound.quantity=" << i2cpParameters.getOutbound_quantity().toStdString() << "\n"; - if (i2cpParameters.getCrypto_tagsToSend().toUShort() != 40) - out << "crypto.tagsToSend=" << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; + if (i2cpParameters.getInbound_length().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNEL_LENGTH) + out << i2p::client::I2CP_PARAM_INBOUND_TUNNEL_LENGTH << "=" + << i2cpParameters.getInbound_length().toStdString() << "\n"; + if (i2cpParameters.getOutbound_length().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNEL_LENGTH) + out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH << "=" + << i2cpParameters.getOutbound_length().toStdString() << "\n"; + if (i2cpParameters.getInbound_quantity().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNELS_QUANTITY) + out << i2p::client::I2CP_PARAM_INBOUND_TUNNELS_QUANTITY << "=" + << i2cpParameters.getInbound_quantity().toStdString() << "\n"; + if (i2cpParameters.getOutbound_quantity().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNELS_QUANTITY) + out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY << "=" + << i2cpParameters.getOutbound_quantity().toStdString() << "\n"; + if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND) + out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "=" + << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; if (!i2cpParameters.getExplicitPeers().isEmpty()) - out << "explicitPeers=" << i2cpParameters.getExplicitPeers().toStdString() << "\n"; + out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" + << i2cpParameters.getExplicitPeers().toStdString() << "\n"; out << "\n"; } diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h index 087ec30b..c714a4f5 100644 --- a/qt/i2pd_qt/TunnelConfig.h +++ b/qt/i2pd_qt/TunnelConfig.h @@ -5,6 +5,7 @@ #include #include "../../libi2pd_client/ClientContext.h" +#include "../../libi2pd/Destination.h" #include "TunnelsPageUpdateListener.h" From ef30d2d3b64ea198a0508d5268656db13779d919 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 15:59:19 +0800 Subject: [PATCH 35/81] fixes #945 --- qt/i2pd_qt/ClientTunnelPane.cpp | 1 + qt/i2pd_qt/ServerTunnelPane.cpp | 1 + qt/i2pd_qt/TunnelPane.cpp | 4 ++++ qt/i2pd_qt/TunnelPane.h | 3 +++ qt/i2pd_qt/widgetlock.h | 4 +++- qt/i2pd_qt/widgetlockregistry.h | 16 ++++++++++------ 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 537abb1c..7f00cb31 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -11,6 +11,7 @@ void ClientTunnelPane::setGroupBoxTitle(const QString & title) { } void ClientTunnelPane::deleteClientTunnelForm() { + TunnelPane::deleteTunnelForm(); delete clientTunnelNameGroupBox; clientTunnelNameGroupBox=nullptr; diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index cc024386..827f6a37 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -266,6 +266,7 @@ int ServerTunnelPane::appendServerTunnelForm( } void ServerTunnelPane::deleteServerTunnelForm() { + TunnelPane::deleteTunnelForm(); delete serverTunnelNameGroupBox;//->deleteLater(); serverTunnelNameGroupBox=nullptr; diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 84e8aed0..5f412070 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -218,3 +218,7 @@ QString TunnelPane::readTunnelTypeComboboxData() { i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) { return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt(); } + +void TunnelPane::deleteTunnelForm() { + widgetlocks.deleteListeners(); +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index f306e9dc..abf0b42d 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -31,6 +31,9 @@ public: TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf); virtual ~TunnelPane(){} + void deleteTunnelForm(); + + virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; diff --git a/qt/i2pd_qt/widgetlock.h b/qt/i2pd_qt/widgetlock.h index 513f328a..5b21125c 100644 --- a/qt/i2pd_qt/widgetlock.h +++ b/qt/i2pd_qt/widgetlock.h @@ -12,6 +12,7 @@ class widgetlock : public QObject { private: QWidget* widget; QPushButton* lockButton; + public slots: void lockButtonClicked(bool) { bool wasEnabled = widget->isEnabled(); @@ -25,7 +26,8 @@ public: lockButton->setText(lockButton->tr("Edit")); QObject::connect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); } - virtual ~widgetlock() { + virtual ~widgetlock() {} + void deleteListener() { QObject::disconnect(lockButton,SIGNAL(clicked(bool)), this, SLOT(lockButtonClicked(bool))); } }; diff --git a/qt/i2pd_qt/widgetlockregistry.h b/qt/i2pd_qt/widgetlockregistry.h index 1091af43..78ee142a 100644 --- a/qt/i2pd_qt/widgetlockregistry.h +++ b/qt/i2pd_qt/widgetlockregistry.h @@ -9,15 +9,19 @@ class widgetlockregistry { public: widgetlockregistry() : locks() {} - virtual ~widgetlockregistry() { - while(!locks.empty()) { - delete locks.back(); - locks.pop_back(); - } - } + virtual ~widgetlockregistry() {} void add(widgetlock* lock) { locks.push_back(lock); } + + void deleteListeners() { + while(!locks.empty()) { + widgetlock* lock = locks.back(); + lock->deleteListener(); + delete lock; + locks.pop_back(); + } + } }; #endif // WIDGETLOCKREGISTRY_H From 9441c1cffecf988077690839f87a5132e4cab10e Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 17:57:15 +0800 Subject: [PATCH 36/81] fixed #935 --- qt/i2pd_qt/ClientTunnelPane.cpp | 4 +- qt/i2pd_qt/ClientTunnelPane.h | 14 +- qt/i2pd_qt/ServerTunnelPane.cpp | 4 +- qt/i2pd_qt/ServerTunnelPane.h | 18 +- qt/i2pd_qt/TunnelConfig.cpp | 36 +- qt/i2pd_qt/TunnelPane.cpp | 4 +- qt/i2pd_qt/TunnelPane.h | 11 +- qt/i2pd_qt/mainwindow.cpp | 31 +- qt/i2pd_qt/mainwindow.h | 64 +- qt/i2pd_qt/mainwindow.ui | 1030 ++++++++++++++++++++++--------- 10 files changed, 863 insertions(+), 353 deletions(-) diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 7f00cb31..4d4bb5ce 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -3,8 +3,8 @@ #include "SignatureTypeComboboxFactory.h" #include "QVBoxLayout" -ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf): - TunnelPane(tunnelsPageUpdateListener, tunconf) {} +ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_): + TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_) {} void ClientTunnelPane::setGroupBoxTitle(const QString & title) { clientTunnelNameGroupBox->setTitle(title); diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index 511209e5..0b80103e 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -14,7 +14,7 @@ class TunnelPane; class ClientTunnelPane : public TunnelPane { Q_OBJECT public: - ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf); + ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_); virtual ~ClientTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); @@ -68,6 +68,7 @@ private: } protected: virtual bool applyDataFromUIToTunnelConfig() { + QString cannotSaveSettings = QApplication::tr("Cannot save settings."); bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); if(!ok)return false; ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); @@ -78,7 +79,11 @@ protected: auto portStr=portLineEdit->text(); int portInt=portStr.toInt(&ok); - if(!ok)return false; + + if(!ok){ + highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit); + return false; + } ctc->setport(portInt); ctc->setkeys(keysLineEdit->text().toStdString()); @@ -87,7 +92,10 @@ protected: auto dportStr=destinationPortLineEdit->text(); int dportInt=dportStr.toInt(&ok); - if(!ok)return false; + if(!ok){ + highlightWrongInput(QApplication::tr("Bad destinationPort, must be int.")+" "+cannotSaveSettings,destinationPortLineEdit); + return false; + } ctc->setdestinationPort(dportInt); ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index 827f6a37..a2ba9558 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -2,8 +2,8 @@ #include "ClientContext.h" #include "SignatureTypeComboboxFactory.h" -ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf): - TunnelPane(tunnelsPageUpdateListener, tunconf) {} +ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_): + TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_) {} void ServerTunnelPane::setGroupBoxTitle(const QString & title) { serverTunnelNameGroupBox->setTitle(title); diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index 4069e339..b7b5ef1c 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -31,7 +31,7 @@ class ServerTunnelPane : public TunnelPane { Q_OBJECT public: - ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf); + ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_); virtual ~ServerTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); @@ -119,6 +119,7 @@ private: protected: virtual bool applyDataFromUIToTunnelConfig() { + QString cannotSaveSettings = QApplication::tr("Cannot save settings."); bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); if(!ok)return false; ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); @@ -127,14 +128,20 @@ protected: auto portStr=portLineEdit->text(); int portInt=portStr.toInt(&ok); - if(!ok)return false; + if(!ok){ + highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit); + return false; + } stc->setport(portInt); stc->setkeys(keysLineEdit->text().toStdString()); auto str=inPortLineEdit->text(); int inPortInt=str.toInt(&ok); - if(!ok)return false; + if(!ok){ + highlightWrongInput(QApplication::tr("Bad inPort, must be int.")+" "+cannotSaveSettings,inPortLineEdit); + return false; + } stc->setinPort(inPortInt); stc->setaccessList(accessListLineEdit->text().toStdString()); @@ -147,7 +154,10 @@ protected: auto mcStr=maxConnsLineEdit->text(); uint32_t mcInt=(uint32_t)mcStr.toInt(&ok); - if(!ok)return false; + if(!ok){ + highlightWrongInput(QApplication::tr("Bad maxConns, must be int.")+" "+cannotSaveSettings,maxConnsLineEdit); + return false; + } stc->setmaxConns(mcInt); stc->setgzip(gzipCheckBox->isChecked()); diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index 8cf86d14..81216c0b 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -6,24 +6,24 @@ void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { } void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { - if (i2cpParameters.getInbound_length().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNEL_LENGTH) - out << i2p::client::I2CP_PARAM_INBOUND_TUNNEL_LENGTH << "=" - << i2cpParameters.getInbound_length().toStdString() << "\n"; - if (i2cpParameters.getOutbound_length().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNEL_LENGTH) - out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH << "=" - << i2cpParameters.getOutbound_length().toStdString() << "\n"; - if (i2cpParameters.getInbound_quantity().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNELS_QUANTITY) - out << i2p::client::I2CP_PARAM_INBOUND_TUNNELS_QUANTITY << "=" - << i2cpParameters.getInbound_quantity().toStdString() << "\n"; - if (i2cpParameters.getOutbound_quantity().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNELS_QUANTITY) - out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY << "=" - << i2cpParameters.getOutbound_quantity().toStdString() << "\n"; - if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND) - out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "=" - << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; - if (!i2cpParameters.getExplicitPeers().isEmpty()) - out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" - << i2cpParameters.getExplicitPeers().toStdString() << "\n"; + if (i2cpParameters.getInbound_length().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNEL_LENGTH) + out << i2p::client::I2CP_PARAM_INBOUND_TUNNEL_LENGTH << "=" + << i2cpParameters.getInbound_length().toStdString() << "\n"; + if (i2cpParameters.getOutbound_length().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNEL_LENGTH) + out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH << "=" + << i2cpParameters.getOutbound_length().toStdString() << "\n"; + if (i2cpParameters.getInbound_quantity().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNELS_QUANTITY) + out << i2p::client::I2CP_PARAM_INBOUND_TUNNELS_QUANTITY << "=" + << i2cpParameters.getInbound_quantity().toStdString() << "\n"; + if (i2cpParameters.getOutbound_quantity().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNELS_QUANTITY) + out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY << "=" + << i2cpParameters.getOutbound_quantity().toStdString() << "\n"; + if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND) + out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "=" + << i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; + if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947 + out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" + << i2cpParameters.getExplicitPeers().toStdString() << "\n"; out << "\n"; } diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 5f412070..a86adbb1 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -1,8 +1,10 @@ #include "TunnelPane.h" #include "QMessageBox" -TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_): +TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_): QObject(), + wrongInputPane(wrongInputPane_), + wrongInputLabel(wrongInputLabel_), tunnelConfig(tunnelConfig_), tunnelsPageUpdateListener(tunnelsPageUpdateListener_), gridLayoutWidget_2(nullptr) {} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index abf0b42d..8d28f07f 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -28,16 +28,24 @@ class TunnelPane : public QObject { Q_OBJECT public: - TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf); + TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_); virtual ~TunnelPane(){} void deleteTunnelForm(); + void hideWrongInputLabel() { wrongInputPane->setVisible(false); } + void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { + wrongInputPane->setVisible(true); + wrongInputLabel->setText(warningText); + if(controlWithWrongInput)controlWithWrongInput->setFocus(); + } virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; protected: + QWidget * wrongInputPane; + QLabel* wrongInputLabel; TunnelConfig* tunnelConfig; widgetlockregistry widgetlocks; TunnelsPageUpdateListener* tunnelsPageUpdateListener; @@ -87,6 +95,7 @@ protected: //returns false when invalid data at UI virtual bool applyDataFromUIToTunnelConfig() { + hideWrongInputLabel(); tunnelConfig->setName(nameLineEdit->text().toStdString()); tunnelConfig->setType(readTunnelTypeComboboxData()); I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 71d7dca7..ec636646 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -82,6 +82,11 @@ MainWindow::MainWindow(QWidget *parent) : ui->settingsContents->setAutoFillBackground(true); ui->settingsContents->setPalette(pal); */ + QPalette pal(palette()); + pal.setColor(QPalette::Background, Qt::red); + ui->wrongInputLabel->setAutoFillBackground(true); + ui->wrongInputLabel->setPalette(pal); + ui->wrongInputLabel->setVisible(false); #ifndef ANDROID createActions(); @@ -565,7 +570,7 @@ void MainWindow::initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, Q configItems.append(new UInt16StringItem(option, numberLineEdit, fieldNameTranslated)); } void MainWindow::initStringBox(ConfigOption option, QLineEdit* lineEdit){ - configItems.append(new BaseStringItem(option, lineEdit)); + configItems.append(new BaseStringItem(option, lineEdit, QString())); } NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) { NonGUIOptionItem * retValue; @@ -623,6 +628,9 @@ void MainWindow::loadAllConfigs(){ } /** returns false iff not valid items present and save was aborted */ bool MainWindow::saveAllConfigs(){ + QString cannotSaveSettings = QApplication::tr("Cannot save settings."); + ui->wrongInputLabel->setVisible(false); + programOptionsWriterCurrentSection=""; /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); else logOption->optionValue=boost::any(std::string("stdout"));*/ @@ -632,7 +640,10 @@ bool MainWindow::saveAllConfigs(){ std::stringstream out; for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { MainWindowItem* item = *it; - if(!item->isValid()) return false; + if(!item->isValid()){ + highlightWrongInput(QApplication::tr("Invalid value for")+" "+item->getConfigOption().section+"::"+item->getConfigOption().option+". "+item->getRequirementToBeValid()+" "+cannotSaveSettings, item->getWidgetToFocus()); + return false; + } } for(QList::iterator it = configItems.begin(); it!= configItems.end(); ++it) { @@ -688,27 +699,27 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { TunnelConfig* tunconf = it->second; ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ - ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc); + ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel); int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; - qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); + //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); continue; } ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ - ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc); + ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel); int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; - qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); + //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); continue; } throw "unknown TunnelConfig subtype"; } - qDebug() << "tun.setting height:" << height; + //qDebug() << "tun.setting height:" << height; ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height)); QList childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren(); foreach(QWidget* widget, childWidgets) @@ -833,3 +844,9 @@ void MainWindow::anchorClickedHandler(const QUrl & link) { void MainWindow::backClickedFromChild() { showStatusPage(statusPage); } + +void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus) { + ui->wrongInputLabel->setVisible(true); + ui->wrongInputLabel->setText(warningText); + if(widgetToFocus)widgetToFocus->setFocus(); +} diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index c0286d03..46294084 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -93,8 +93,13 @@ class MainWindow; class MainWindowItem : public QObject { Q_OBJECT ConfigOption option; + QWidget* widgetToFocus; + QString requirementToBeValid; public: - MainWindowItem(ConfigOption option_) : option(option_) {} + MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {} + QWidget* getWidgetToFocus(){return widgetToFocus;} + QString& getRequirementToBeValid() { return requirementToBeValid; } + ConfigOption& getConfigOption() { return option; } boost::any optionValue; virtual ~MainWindowItem(){} virtual void installListeners(MainWindow *mainWindow); @@ -145,7 +150,7 @@ public: }; class NonGUIOptionItem : public MainWindowItem { public: - NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_) {}; + NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {}; virtual ~NonGUIOptionItem(){} virtual bool isValid() { return true; } }; @@ -153,7 +158,7 @@ class BaseStringItem : public MainWindowItem { Q_OBJECT public: QLineEdit* lineEdit; - BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_) : MainWindowItem(option_), lineEdit(lineEdit_){}; + BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_) : MainWindowItem(option_, lineEdit_, requirementToBeValid_), lineEdit(lineEdit_){}; virtual ~BaseStringItem(){} virtual void installListeners(MainWindow *mainWindow); virtual QString toString(){ @@ -175,7 +180,7 @@ class FileOrFolderChooserItem : public BaseStringItem { public: QPushButton* browsePushButton; FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) : - BaseStringItem(option_, lineEdit_), browsePushButton(browsePushButton_) {} + BaseStringItem(option_, lineEdit_, QString()), browsePushButton(browsePushButton_) {} virtual ~FileOrFolderChooserItem(){} }; class FileChooserItem : public FileOrFolderChooserItem { @@ -201,7 +206,7 @@ public: class ComboBoxItem : public MainWindowItem { public: QComboBox* comboBox; - ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_), comboBox(comboBox_){}; + ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){}; virtual ~ComboBoxItem(){} virtual void installListeners(MainWindow *mainWindow); virtual void loadFromConfigOption()=0; @@ -260,7 +265,7 @@ public: class CheckBoxItem : public MainWindowItem { public: QCheckBox* checkBox; - CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_), checkBox(checkBox_){}; + CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){}; virtual ~CheckBoxItem(){} virtual void installListeners(MainWindow *mainWindow); virtual void loadFromConfigOption(){ @@ -276,58 +281,77 @@ public: class BaseFormattedStringItem : public BaseStringItem { public: QString fieldNameTranslated; - BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseStringItem(option_, lineEdit_), fieldNameTranslated(fieldNameTranslated_) {}; + BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_) : + BaseStringItem(option_, lineEdit_, requirementToBeValid_), fieldNameTranslated(fieldNameTranslated_) {}; virtual ~BaseFormattedStringItem(){} virtual bool isValid()=0; }; class IntegerStringItem : public BaseFormattedStringItem { public: IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer.")) {}; virtual ~IntegerStringItem(){} - virtual bool isValid(){return true;} + virtual bool isValid(){ + auto str=lineEdit->text(); + bool ok; + str.toInt(&ok); + return ok; + } virtual QString toString(){return QString::number(boost::any_cast(optionValue));} virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));} }; class UShortStringItem : public BaseFormattedStringItem { public: UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer.")) {}; virtual ~UShortStringItem(){} - virtual bool isValid(){return true;} + virtual bool isValid(){ + auto str=lineEdit->text(); + bool ok; + str.toUShort(&ok); + return ok; + } virtual QString toString(){return QString::number(boost::any_cast(optionValue));} virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));} }; class UInt32StringItem : public BaseFormattedStringItem { public: UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer.")) {}; virtual ~UInt32StringItem(){} - virtual bool isValid(){return true;} + virtual bool isValid(){ + auto str=lineEdit->text(); + bool ok; + str.toUInt(&ok); + return ok; + } virtual QString toString(){return QString::number(boost::any_cast(optionValue));} virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));} }; class UInt16StringItem : public BaseFormattedStringItem { public: UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer")) {}; virtual ~UInt16StringItem(){} - virtual bool isValid(){return true;} + virtual bool isValid(){ + auto str=lineEdit->text(); + bool ok; + str.toUShort(&ok); + return ok; + } virtual QString toString(){return QString::number(boost::any_cast(optionValue));} virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));} }; class IPAddressStringItem : public BaseFormattedStringItem { public: IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_) {}; - virtual bool isValid(){return true;} + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address")) {}; + virtual bool isValid(){return true;}//todo }; class TCPPortStringItem : public UShortStringItem { public: TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {}; - virtual bool isValid(){return true;} }; namespace Ui { @@ -354,6 +378,8 @@ public: void setI2PController(i2p::qt::Controller* controller_); + void highlightWrongInput(QString warningText, QWidget* widgetToFocus); + //typedef std::function DefaultValueGetter; //#ifndef ANDROID diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index cf15155b..2363614b 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -50,7 +50,7 @@ 10 10 888 - 530 + 555 @@ -168,332 +168,770 @@ - - - - 0 - 0 - - - - - 0 - 528 - - - - - 713 - 713 - - - - 1 - - - - - 0 - 0 - - - - - - 0 - 0 - 713 - 531 - + + + + + + 0 + 30 + - - - QLayout::SetMaximumSize + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 63 + 63 + + + + + + + 127 + 0 + 0 + + + + + + + 170 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 63 + 63 + + + + + + + 127 + 0 + 0 + + + + + + + 170 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + + 127 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 127 + 127 + + + + + + + 255 + 63 + 63 + + + + + + + 127 + 0 + 0 + + + + + + + 170 + 0 + 0 + + + + + + + 127 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 127 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 255 + 220 + + + + + + + 0 + 0 + 0 + + + + + + + + TextLabel + + + true + + + 10 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 713 + 713 + + + + 0 + + + + + 0 + 0 + - - - - - 15 - - - - Status - - - - - + + + + 0 + 0 + 713 + 531 + + + QLayout::SetMaximumSize + + + + + 15 + + + + Status + + + + + + + QLayout::SetMaximumSize + + + - - - - - - - - 0 - 0 - - - - - - 0 - 0 - 711 - 531 - - - - - QLayout::SetMaximumSize + + + + + + 0 + 0 + - - - - - 15 - + + + + 0 + 0 + 711 + 531 + + + + + QLayout::SetMaximumSize - - General settings - - - - - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustIgnored - - - true - - - - - 0 - 0 - 689 - 496 - - - - - 0 - 0 - - - - - -
-
- - - - - - 0 - 0 - 711 - 531 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Tunnels settings - - - - - - + + + + 15 + + - Add Client Tunnel + General settings - + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustIgnored + + + true + + + + + 0 + 0 + 80 + 26 + + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + 711 + 531 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + - Add Server Tunnel + Tunnels settings - + + + + + Add Client Tunnel + + + + + + + Add Server Tunnel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::ScrollBarAlwaysOn + + + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 699 + 425 + + + + + + + + + + + + + 0 + 0 + 711 + 531 + + + + + QLayout::SetMinAndMaxSize + + + + + + 15 + + + + Restart + + + + + + + Restart i2pd + + + + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 - - - - - Qt::ScrollBarAlwaysOn - - - false - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 699 - 425 - - - - - -
- - - - - - - 0 - 0 - 711 - 531 - - - - - QLayout::SetMinAndMaxSize + + + + + + 0 + 0 + - - - - - 15 - + + + + 0 + 0 + 711 + 531 + + + + + QLayout::SetMinAndMaxSize - - Restart - - - - - - - Restart i2pd - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + + + 15 + + + + Quit + + + + + + + Quit Now + + + + + + + Graceful Quit + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + - - - - - 0 - 0 - - - - - - 0 - 0 - 711 - 531 - - - - - QLayout::SetMinAndMaxSize - - - - - - 15 - - - - Quit - - - - - - - Quit Now - - - - - - - Graceful Quit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - + + From 1efc2a9b5dd80402f4f7f3399c1e7a573b2dfce6 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 18:02:12 +0800 Subject: [PATCH 37/81] little ui fixes --- qt/i2pd_qt/generalsettingswidget.ui | 4 ++-- qt/i2pd_qt/mainwindow.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qt/i2pd_qt/generalsettingswidget.ui b/qt/i2pd_qt/generalsettingswidget.ui index 6af16ecf..a7f07e5d 100644 --- a/qt/i2pd_qt/generalsettingswidget.ui +++ b/qt/i2pd_qt/generalsettingswidget.ui @@ -929,7 +929,7 @@ - Port (leave empty to auto-assign): + Port (leave 0 to auto-assign): @@ -1500,7 +1500,7 @@ - Bandwidth limit (integer): + Bandwidth limit (integer or a letter): diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 46294084..1805ad87 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -331,7 +331,7 @@ public: class UInt16StringItem : public BaseFormattedStringItem { public: UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) : - BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer")) {}; + BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer.")) {}; virtual ~UInt16StringItem(){} virtual bool isValid(){ auto str=lineEdit->text(); From 96cb663fa8ce218065350f9d3ae3a4183f6c9cec Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 18:58:04 +0800 Subject: [PATCH 38/81] some work + fixed red errors on malformed input --- qt/i2pd_qt/ClientTunnelPane.cpp | 4 ++-- qt/i2pd_qt/ClientTunnelPane.h | 2 +- qt/i2pd_qt/ServerTunnelPane.cpp | 4 ++-- qt/i2pd_qt/ServerTunnelPane.h | 8 ++++---- qt/i2pd_qt/TunnelPane.cpp | 16 +++++++++++++--- qt/i2pd_qt/TunnelPane.h | 16 ++++++++-------- qt/i2pd_qt/mainwindow.cpp | 26 +++++++++++++++++++++----- qt/i2pd_qt/mainwindow.h | 10 +++++----- qt/i2pd_qt/mainwindow.ui | 6 +++--- 9 files changed, 59 insertions(+), 33 deletions(-) diff --git a/qt/i2pd_qt/ClientTunnelPane.cpp b/qt/i2pd_qt/ClientTunnelPane.cpp index 4d4bb5ce..256d0510 100644 --- a/qt/i2pd_qt/ClientTunnelPane.cpp +++ b/qt/i2pd_qt/ClientTunnelPane.cpp @@ -3,8 +3,8 @@ #include "SignatureTypeComboboxFactory.h" #include "QVBoxLayout" -ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_): - TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_) {} +ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow): + TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {} void ClientTunnelPane::setGroupBoxTitle(const QString & title) { clientTunnelNameGroupBox->setTitle(title); diff --git a/qt/i2pd_qt/ClientTunnelPane.h b/qt/i2pd_qt/ClientTunnelPane.h index 0b80103e..c2e076b7 100644 --- a/qt/i2pd_qt/ClientTunnelPane.h +++ b/qt/i2pd_qt/ClientTunnelPane.h @@ -14,7 +14,7 @@ class TunnelPane; class ClientTunnelPane : public TunnelPane { Q_OBJECT public: - ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_); + ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow); virtual ~ClientTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); virtual ClientTunnelPane* asClientTunnelPane(); diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp index a2ba9558..029a3ea2 100644 --- a/qt/i2pd_qt/ServerTunnelPane.cpp +++ b/qt/i2pd_qt/ServerTunnelPane.cpp @@ -2,8 +2,8 @@ #include "ClientContext.h" #include "SignatureTypeComboboxFactory.h" -ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_): - TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_) {} +ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow): + TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {} void ServerTunnelPane::setGroupBoxTitle(const QString & title) { serverTunnelNameGroupBox->setTitle(title); diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h index b7b5ef1c..556c8473 100644 --- a/qt/i2pd_qt/ServerTunnelPane.h +++ b/qt/i2pd_qt/ServerTunnelPane.h @@ -1,9 +1,6 @@ #ifndef SERVERTUNNELPANE_H #define SERVERTUNNELPANE_H -#include "TunnelPane.h" -#include "TunnelsPageUpdateListener.h" - #include #include #include @@ -23,6 +20,9 @@ #include "assert.h" +#include "TunnelPane.h" +#include "TunnelsPageUpdateListener.h" + class ServerTunnelConfig; class ClientTunnelPane; @@ -31,7 +31,7 @@ class ServerTunnelPane : public TunnelPane { Q_OBJECT public: - ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_); + ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow); virtual ~ServerTunnelPane(){} virtual ServerTunnelPane* asServerTunnelPane(); diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index a86adbb1..48adcf78 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -1,8 +1,11 @@ #include "TunnelPane.h" -#include "QMessageBox" -TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_): +#include "QMessageBox" +#include "mainwindow.h" + +TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_): QObject(), + mainWindow(mainWindow_), wrongInputPane(wrongInputPane_), wrongInputLabel(wrongInputLabel_), tunnelConfig(tunnelConfig_), @@ -181,7 +184,7 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, void TunnelPane::updated() { std::string oldName=tunnelConfig->getName(); - if(!applyDataFromUIToTunnelConfig())return;//TODO visualise bad input + if(!applyDataFromUIToTunnelConfig())return; tunnelsPageUpdateListener->updated(oldName, tunnelConfig); } @@ -224,3 +227,10 @@ i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeCo void TunnelPane::deleteTunnelForm() { widgetlocks.deleteListeners(); } + +void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { + wrongInputPane->setVisible(true); + wrongInputLabel->setText(warningText); + if(controlWithWrongInput)controlWithWrongInput->setFocus(); + mainWindow->showTunnelsPage(); +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 8d28f07f..3a647635 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -23,27 +23,26 @@ class ClientTunnelPane; class TunnelConfig; class I2CPParameters; +class MainWindow; + class TunnelPane : public QObject { Q_OBJECT public: - TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_); + TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_); virtual ~TunnelPane(){} void deleteTunnelForm(); - void hideWrongInputLabel() { wrongInputPane->setVisible(false); } - void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { - wrongInputPane->setVisible(true); - wrongInputLabel->setText(warningText); - if(controlWithWrongInput)controlWithWrongInput->setFocus(); - } + void hideWrongInputLabel() const { wrongInputPane->setVisible(false); } + void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput); virtual ServerTunnelPane* asServerTunnelPane()=0; virtual ClientTunnelPane* asClientTunnelPane()=0; protected: + MainWindow* mainWindow; QWidget * wrongInputPane; QLabel* wrongInputLabel; TunnelConfig* tunnelConfig; @@ -93,6 +92,7 @@ protected: //should be created by factory i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox); +public: //returns false when invalid data at UI virtual bool applyDataFromUIToTunnelConfig() { hideWrongInputLabel(); @@ -106,7 +106,7 @@ protected: i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); return true; } - +protected: void setupTunnelPane( TunnelConfig* tunnelConfig, QGroupBox *tunnelGroupBox, diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index ec636646..7f9810cc 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -699,22 +699,28 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { TunnelConfig* tunconf = it->second; ServerTunnelConfig* stc = tunconf->asServerTunnelConfig(); if(stc){ - ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel); + ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel, this); int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); - if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); + if(name==tunnelNameToFocus){ + tunnelPane->getNameLineEdit()->setFocus(); + //todo ui->settingsScrollArea->###scroll + } continue; } ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig(); if(ctc){ - ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel); + ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel, this); int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height); height+=h; //qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size(); tunnelPanes.push_back(tunnelPane); - if(name==tunnelNameToFocus)tunnelPane->getNameLineEdit()->setFocus(); + if(name==tunnelNameToFocus){ + tunnelPane->getNameLineEdit()->setFocus(); + //todo ui->settingsScrollArea->###scroll + } continue; } throw "unknown TunnelConfig subtype"; @@ -759,6 +765,15 @@ void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { void MainWindow::SaveTunnelsConfig() { std::stringstream out; + //validate and show red if wrong + for (std::list::iterator it=tunnelPanes.begin(); it!=tunnelPanes.end(); ++it) { + TunnelPane* tunpane = *it; + if(!tunpane->applyDataFromUIToTunnelConfig()) { + //!valid + return; + } + } + for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { const std::string& name = it->first; TunnelConfig* tunconf = it->second; @@ -788,7 +803,7 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it); mainWindow->tunnelConfigs[tunConf->getName()]=tunConf; } - mainWindow->SaveTunnelsConfig(); + mainWindow->saveAllConfigs(); } void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){ @@ -849,4 +864,5 @@ void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus ui->wrongInputLabel->setVisible(true); ui->wrongInputLabel->setText(warningText); if(widgetToFocus)widgetToFocus->setFocus(); + showSettingsPage(); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 1805ad87..831ce7b5 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -411,7 +411,7 @@ private slots: void runPeerTest(); void enableTransit(); void disableTransit(); - +public slots: void showStatus_local_destinations_Page(); void showStatus_leasesets_Page(); void showStatus_tunnels_Page(); @@ -572,9 +572,9 @@ private: TunnelConfig* tc=it->second; tunnelConfigs.erase(it); delete tc; - SaveTunnelsConfig(); - reloadTunnelsConfigAndUI(""); } + saveAllConfigs(); + reloadTunnelsConfigAndUI(""); } std::string GenerateNewTunnelName() { @@ -609,7 +609,7 @@ private: destinationPort, sigType); - SaveTunnelsConfig(); + saveAllConfigs(); reloadTunnelsConfigAndUI(name); } @@ -648,7 +648,7 @@ private: isUniqueLocal); - SaveTunnelsConfig(); + saveAllConfigs(); reloadTunnelsConfigAndUI(name); } diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 2363614b..bdd4693d 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -624,7 +624,7 @@ - 0 + 1 @@ -719,8 +719,8 @@ 0 0 - 80 - 26 + 689 + 496 From 81b79e6e5374c792e59a307032102c902ee638fe Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 19:42:25 +0800 Subject: [PATCH 39/81] ui critical fixes --- qt/i2pd_qt/TunnelPane.cpp | 7 ++++++- qt/i2pd_qt/mainwindow.cpp | 15 +++------------ qt/i2pd_qt/mainwindow.h | 3 ++- qt/i2pd_qt/mainwindow.ui | 6 +++--- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 48adcf78..bbf5914d 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -2,6 +2,7 @@ #include "QMessageBox" #include "mainwindow.h" +#include "ui_mainwindow.h" TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_): QObject(), @@ -184,6 +185,7 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, void TunnelPane::updated() { std::string oldName=tunnelConfig->getName(); + //validate and show red if invalid if(!applyDataFromUIToTunnelConfig())return; tunnelsPageUpdateListener->updated(oldName, tunnelConfig); } @@ -231,6 +233,9 @@ void TunnelPane::deleteTunnelForm() { void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { wrongInputPane->setVisible(true); wrongInputLabel->setText(warningText); - if(controlWithWrongInput)controlWithWrongInput->setFocus(); + if(controlWithWrongInput){ + mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput); + controlWithWrongInput->setFocus(); + } mainWindow->showTunnelsPage(); } diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 7f9810cc..aba00cec 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -706,7 +706,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { tunnelPanes.push_back(tunnelPane); if(name==tunnelNameToFocus){ tunnelPane->getNameLineEdit()->setFocus(); - //todo ui->settingsScrollArea->###scroll + ui->tunnelsScrollArea->ensureWidgetVisible(tunnelPane->getNameLineEdit()); } continue; } @@ -719,7 +719,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) { tunnelPanes.push_back(tunnelPane); if(name==tunnelNameToFocus){ tunnelPane->getNameLineEdit()->setFocus(); - //todo ui->settingsScrollArea->###scroll + ui->tunnelsScrollArea->ensureWidgetVisible(tunnelPane->getNameLineEdit()); } continue; } @@ -765,15 +765,6 @@ void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { void MainWindow::SaveTunnelsConfig() { std::stringstream out; - //validate and show red if wrong - for (std::list::iterator it=tunnelPanes.begin(); it!=tunnelPanes.end(); ++it) { - TunnelPane* tunpane = *it; - if(!tunpane->applyDataFromUIToTunnelConfig()) { - //!valid - return; - } - } - for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { const std::string& name = it->first; TunnelConfig* tunconf = it->second; @@ -863,6 +854,6 @@ void MainWindow::backClickedFromChild() { void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus) { ui->wrongInputLabel->setVisible(true); ui->wrongInputLabel->setText(warningText); - if(widgetToFocus)widgetToFocus->setFocus(); + if(widgetToFocus){ui->settingsScrollArea->ensureWidgetVisible(widgetToFocus);widgetToFocus->setFocus();} showSettingsPage(); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 831ce7b5..df8ab1e8 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -441,11 +441,12 @@ private: QMenu *trayIconMenu; #endif +public: Ui::MainWindow* ui; Ui::StatusButtonsForm* statusButtonsUI; Ui::routerCommandsWidget* routerCommandsUI; Ui::GeneralSettingsContentsForm* uiSettings; - +private: TextBrowserTweaked1 * textBrowser; QWidget * routerCommandsParent; PageWithBackButton * pageWithBackButton; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index bdd4693d..b4aaed1d 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 908 - 550 + 554 @@ -50,7 +50,7 @@ 10 10 888 - 555 + 531 @@ -624,7 +624,7 @@ - 1 + 0 From ec76381a0b68f96840c9cae513d52cb86f4a5a24 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 23:07:27 +0800 Subject: [PATCH 40/81] ui beautifying --- qt/i2pd_qt/TunnelPane.cpp | 9 +++++++++ qt/i2pd_qt/TunnelPane.h | 2 +- qt/i2pd_qt/mainwindow.cpp | 30 ++++++++++++++++++++++++++++++ qt/i2pd_qt/mainwindow.h | 3 ++- qt/i2pd_qt/mainwindow.ui | 21 +++++++++++++++------ 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index bbf5914d..a8baed6f 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -231,11 +231,20 @@ void TunnelPane::deleteTunnelForm() { } void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { + bool redVisible = wrongInputPane->isVisible(); wrongInputPane->setVisible(true); wrongInputLabel->setText(warningText); + if(!redVisible)mainWindow->adjustSizesAccordingToWrongLabel(); if(controlWithWrongInput){ mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput); controlWithWrongInput->setFocus(); } mainWindow->showTunnelsPage(); } + +void TunnelPane::hideWrongInputLabel() const { + bool redVisible = wrongInputPane->isVisible(); + wrongInputPane->setVisible(false); + if(redVisible)mainWindow->adjustSizesAccordingToWrongLabel(); + +} diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index 3a647635..d14ba8d0 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -35,7 +35,7 @@ public: void deleteTunnelForm(); - void hideWrongInputLabel() const { wrongInputPane->setVisible(false); } + void hideWrongInputLabel() const; void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput); virtual ServerTunnelPane* asServerTunnelPane()=0; diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index aba00cec..6d7e8b20 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -75,6 +75,7 @@ MainWindow::MainWindow(QWidget *parent) : int w = 683; int h = 3060; ui->settingsContents->setFixedSize(w, h); + ui->settingsContents->setGeometry(QRect(0,0,w,h)); /* QPalette pal(palette()); @@ -86,8 +87,10 @@ MainWindow::MainWindow(QWidget *parent) : pal.setColor(QPalette::Background, Qt::red); ui->wrongInputLabel->setAutoFillBackground(true); ui->wrongInputLabel->setPalette(pal); + ui->wrongInputLabel->setMaximumHeight(ui->wrongInputLabel->sizeHint().height()); ui->wrongInputLabel->setVisible(false); + settingsTitleLabelNominalHeight = ui->settingsTitleLabel->height(); #ifndef ANDROID createActions(); createTrayIcon(); @@ -629,7 +632,9 @@ void MainWindow::loadAllConfigs(){ /** returns false iff not valid items present and save was aborted */ bool MainWindow::saveAllConfigs(){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); + bool redVisible = ui->wrongInputLabel->isVisible(); ui->wrongInputLabel->setVisible(false); + if(redVisible)adjustSizesAccordingToWrongLabel(); programOptionsWriterCurrentSection=""; /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); @@ -851,9 +856,34 @@ void MainWindow::backClickedFromChild() { showStatusPage(statusPage); } +void MainWindow::adjustSizesAccordingToWrongLabel() { + if(ui->wrongInputLabel->isVisible()) { + int dh = ui->wrongInputLabel->height()+ui->verticalLayout_7->layout()->spacing(); + ui->verticalLayout_7->invalidate(); + ui->wrongInputLabel->adjustSize(); + ui->stackedWidget->adjustSize(); + ui->stackedWidget->setFixedHeight(531-dh); + ui->settingsPage->setFixedHeight(531-dh); + ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531-dh)); + ui->stackedWidget->setFixedHeight(531-dh); + ui->settingsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); + }else{ + ui->verticalLayout_7->invalidate(); + ui->wrongInputLabel->adjustSize(); + ui->stackedWidget->adjustSize(); + ui->stackedWidget->setFixedHeight(531); + ui->settingsPage->setFixedHeight(531); + ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531)); + ui->stackedWidget->setFixedHeight(531); + ui->settingsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); + } +} + void MainWindow::highlightWrongInput(QString warningText, QWidget* widgetToFocus) { + bool redVisible = ui->wrongInputLabel->isVisible(); ui->wrongInputLabel->setVisible(true); ui->wrongInputLabel->setText(warningText); + if(!redVisible)adjustSizesAccordingToWrongLabel(); if(widgetToFocus){ui->settingsScrollArea->ensureWidgetVisible(widgetToFocus);widgetToFocus->setFocus();} showSettingsPage(); } diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index df8ab1e8..1b55a6da 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -387,7 +387,6 @@ public: //#endif private: - enum StatusPage {main_page, commands, local_destinations, leasesets, tunnels, transit_tunnels, transports, i2p_tunnels, sam_sessions}; private slots: @@ -446,7 +445,9 @@ public: Ui::StatusButtonsForm* statusButtonsUI; Ui::routerCommandsWidget* routerCommandsUI; Ui::GeneralSettingsContentsForm* uiSettings; + void adjustSizesAccordingToWrongLabel(); private: + int settingsTitleLabelNominalHeight; TextBrowserTweaked1 * textBrowser; QWidget * routerCommandsParent; PageWithBackButton * pageWithBackButton; diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index b4aaed1d..70c3d361 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -169,6 +169,9 @@ + + QLayout::SetMinAndMaxSize + @@ -606,7 +609,7 @@ - + 0 0 @@ -624,11 +627,11 @@ - 0 + 1 - + 0 0 @@ -670,7 +673,7 @@ - + 0 0 @@ -686,7 +689,7 @@ - QLayout::SetMaximumSize + QLayout::SetMinAndMaxSize @@ -702,6 +705,12 @@ + + + 0 + 0 + + Qt::ScrollBarAlwaysOn @@ -869,7 +878,7 @@ - + 0 0 From 21de4709eab6c06a84f4122ced003be7ffd3ca58 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 23:16:54 +0800 Subject: [PATCH 41/81] ui beautifying more --- qt/i2pd_qt/mainwindow.cpp | 6 ++++++ qt/i2pd_qt/mainwindow.ui | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 6d7e8b20..217ec958 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -867,6 +867,9 @@ void MainWindow::adjustSizesAccordingToWrongLabel() { ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531-dh)); ui->stackedWidget->setFixedHeight(531-dh); ui->settingsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); + ui->settingsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); + ui->tunnelsScrollArea->setFixedHeight(531-dh-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing()); + ui->tunnelsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); }else{ ui->verticalLayout_7->invalidate(); ui->wrongInputLabel->adjustSize(); @@ -876,6 +879,9 @@ void MainWindow::adjustSizesAccordingToWrongLabel() { ui->verticalLayoutWidget_4->setGeometry(QRect(0, 0, 711, 531)); ui->stackedWidget->setFixedHeight(531); ui->settingsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->verticalLayout_4->spacing()); + ui->settingsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); + ui->tunnelsScrollArea->setFixedHeight(531-settingsTitleLabelNominalHeight-ui->horizontalLayout_42->geometry().height()-2*ui->verticalLayout_4->spacing()); + ui->tunnelsTitleLabel->setFixedHeight(settingsTitleLabelNominalHeight); } } diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index 70c3d361..9b463f44 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -627,7 +627,7 @@ - 1 + 2 @@ -759,7 +759,7 @@ QLayout::SetMinAndMaxSize - + 15 From 1947be4957bc2bbb1ab5fccb1fc3e7a2bb3c519e Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Fri, 8 Sep 2017 23:25:25 +0800 Subject: [PATCH 42/81] fixed tunnels invalid ui data handling --- qt/i2pd_qt/TunnelPane.cpp | 2 +- qt/i2pd_qt/mainwindow.cpp | 8 ++++++++ qt/i2pd_qt/mainwindow.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index a8baed6f..0cd7b741 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -186,7 +186,7 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, void TunnelPane::updated() { std::string oldName=tunnelConfig->getName(); //validate and show red if invalid - if(!applyDataFromUIToTunnelConfig())return; + if(!mainWindow->applyTunnelsUiToConfigs())return; tunnelsPageUpdateListener->updated(oldName, tunnelConfig); } diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 217ec958..bf26964d 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -756,6 +756,14 @@ void MainWindow::deleteTunnelForms() { tunnelPanes.clear(); } +bool MainWindow::applyTunnelsUiToConfigs() { + for(std::list::iterator it = tunnelPanes.begin(); it != tunnelPanes.end(); ++it) { + TunnelPane* tp = *it; + if(!tp->applyDataFromUIToTunnelConfig())return false; + } + return true; +} + void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) { deleteTunnelForms(); for (std::map::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) { diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 1b55a6da..3b65d3c2 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -446,6 +446,7 @@ public: Ui::routerCommandsWidget* routerCommandsUI; Ui::GeneralSettingsContentsForm* uiSettings; void adjustSizesAccordingToWrongLabel(); + bool applyTunnelsUiToConfigs(); private: int settingsTitleLabelNominalHeight; TextBrowserTweaked1 * textBrowser; From cd3f274763f2fba12f5eaeecb1d13ae35f0b4107 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 9 Sep 2017 01:09:31 +0800 Subject: [PATCH 43/81] fixed tunnels invalid ui data handling 2 --- qt/i2pd_qt/TunnelPane.cpp | 1 + qt/i2pd_qt/TunnelPane.h | 1 - qt/i2pd_qt/mainwindow.cpp | 17 ++++++++++------- qt/i2pd_qt/mainwindow.h | 1 + 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index 0cd7b741..b3cc3bef 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -186,6 +186,7 @@ void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, void TunnelPane::updated() { std::string oldName=tunnelConfig->getName(); //validate and show red if invalid + hideWrongInputLabel(); if(!mainWindow->applyTunnelsUiToConfigs())return; tunnelsPageUpdateListener->updated(oldName, tunnelConfig); } diff --git a/qt/i2pd_qt/TunnelPane.h b/qt/i2pd_qt/TunnelPane.h index d14ba8d0..a7012810 100644 --- a/qt/i2pd_qt/TunnelPane.h +++ b/qt/i2pd_qt/TunnelPane.h @@ -95,7 +95,6 @@ protected: public: //returns false when invalid data at UI virtual bool applyDataFromUIToTunnelConfig() { - hideWrongInputLabel(); tunnelConfig->setName(nameLineEdit->text().toStdString()); tunnelConfig->setType(readTunnelTypeComboboxData()); I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index bf26964d..93da099a 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -632,10 +632,6 @@ void MainWindow::loadAllConfigs(){ /** returns false iff not valid items present and save was aborted */ bool MainWindow::saveAllConfigs(){ QString cannotSaveSettings = QApplication::tr("Cannot save settings."); - bool redVisible = ui->wrongInputLabel->isVisible(); - ui->wrongInputLabel->setVisible(false); - if(redVisible)adjustSizesAccordingToWrongLabel(); - programOptionsWriterCurrentSection=""; /*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file")); else logOption->optionValue=boost::any(std::string("stdout"));*/ @@ -684,15 +680,22 @@ void FolderChooserItem::pushButtonReleased() { } void BaseStringItem::installListeners(MainWindow *mainWindow) { - QObject::connect(lineEdit, SIGNAL(textChanged(const QString &)), mainWindow, SLOT(saveAllConfigs())); + QObject::connect(lineEdit, SIGNAL(textChanged(const QString &)), mainWindow, SLOT(updated())); } void ComboBoxItem::installListeners(MainWindow *mainWindow) { - QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), mainWindow, SLOT(saveAllConfigs())); + QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)), mainWindow, SLOT(updated())); } void CheckBoxItem::installListeners(MainWindow *mainWindow) { - QObject::connect(checkBox, SIGNAL(stateChanged(int)), mainWindow, SLOT(saveAllConfigs())); + QObject::connect(checkBox, SIGNAL(stateChanged(int)), mainWindow, SLOT(updated())); } +void MainWindow::updated() { + ui->wrongInputLabel->setVisible(false); + adjustSizesAccordingToWrongLabel(); + + applyTunnelsUiToConfigs(); + saveAllConfigs(); +} void MainWindowItem::installListeners(MainWindow *mainWindow) {} diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 3b65d3c2..7e55a65f 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -390,6 +390,7 @@ private: enum StatusPage {main_page, commands, local_destinations, leasesets, tunnels, transit_tunnels, transports, i2p_tunnels, sam_sessions}; private slots: + void updated(); void handleQuitButton(); void handleGracefulQuitButton(); From d4e16881ff65a4c933ef53a023bf8b25ac1638ca Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 9 Sep 2017 01:13:42 +0800 Subject: [PATCH 44/81] fixed tunnels invalid ui data handling 3 --- qt/i2pd_qt/TunnelPane.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qt/i2pd_qt/TunnelPane.cpp b/qt/i2pd_qt/TunnelPane.cpp index b3cc3bef..fb840276 100644 --- a/qt/i2pd_qt/TunnelPane.cpp +++ b/qt/i2pd_qt/TunnelPane.cpp @@ -200,6 +200,7 @@ void TunnelPane::deleteButtonReleased() { switch (ret) { case QMessageBox::Ok: // OK was clicked + hideWrongInputLabel(); tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName()); break; case QMessageBox::Cancel: @@ -232,10 +233,9 @@ void TunnelPane::deleteTunnelForm() { } void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { - bool redVisible = wrongInputPane->isVisible(); wrongInputPane->setVisible(true); wrongInputLabel->setText(warningText); - if(!redVisible)mainWindow->adjustSizesAccordingToWrongLabel(); + mainWindow->adjustSizesAccordingToWrongLabel(); if(controlWithWrongInput){ mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput); controlWithWrongInput->setFocus(); @@ -244,8 +244,6 @@ void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWr } void TunnelPane::hideWrongInputLabel() const { - bool redVisible = wrongInputPane->isVisible(); wrongInputPane->setVisible(false); - if(redVisible)mainWindow->adjustSizesAccordingToWrongLabel(); - + mainWindow->adjustSizesAccordingToWrongLabel(); } From fd6827fdca5912f1577ca40a8b5b124ddfb6322c Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sat, 9 Sep 2017 20:13:45 +0300 Subject: [PATCH 45/81] add space --- libi2pd_client/ClientContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 08c164ae..743c1388 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -568,7 +568,7 @@ namespace client { // TODO: update ins.first->second->isUpdated = true; - LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, "already exists"); + LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists"); } } } From d59d36f93cc8ec0c9be0aafc8dace91d963235a3 Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 11 Sep 2017 07:48:10 -0400 Subject: [PATCH 46/81] fix up homebrew makefile --- Makefile.homebrew | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Makefile.homebrew b/Makefile.homebrew index 1cce3232..4f69ae36 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -1,17 +1,29 @@ # root directory holding homebrew -BREWROOT = /usr/local/ +BREWROOT = /usr/local BOOSTROOT = ${BREWROOT}/opt/boost SSLROOT = ${BREWROOT}/opt/libressl +UPNPROOT = ${BREWROOT}/opt/miniupnpc CXX = clang++ -CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include +CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual +INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include + +ifeq ($(USE_STATIC),yes) +LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_date_time.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a -lpthread +else LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread +endif ifeq ($(USE_UPNP),yes) LDFLAGS += -ldl CXXFLAGS += -DUSE_UPNP - LDLIBS += -lminiupnpc + INCFLAGS += -I${UPNPROOT}/include + ifeq ($(USE_STATIC),yes) + LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a + else + LDFLAGS += -L${UPNPROOT}/lib + LDLIBS += -lminiupnpc + endif endif # OSX Notes From 330fab2efa49205709f6a0523eeac514fd24c39c Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 11 Sep 2017 08:57:43 -0400 Subject: [PATCH 47/81] update macos i2pd qt build to statically compile in libraries for portability --- qt/i2pd_qt/i2pd_qt.pro | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 4fd1d38f..78078904 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -189,6 +189,24 @@ FORMS += mainwindow.ui \ LIBS += -lz +macx { + message("using mac os x target") + BREWROOT=/usr/local + BOOSTROOT=$$BREWROOT/opt/boost + SSLROOT=$$BREWROOT/opt/libressl + UPNPROOT=$$BREWROOT/opt/miniupnpc + INCLUDEPATH += $$BOOSTROOT/include + INCLUDEPATH += $$SSLROOT/include + INCLUDEPATH += $$UPNPROOT/include + LIBS += $$SSLROOT/lib/libcrypto.a + LIBS += $$SSLROOT/lib/libssl.a + LIBS += $$BOOSTROOT/lib/libboost_system.a + LIBS += $$BOOSTROOT/lib/libboost_date_time.a + LIBS += $$BOOSTROOT/lib/libboost_filesystem.a + LIBS += $$BOOSTROOT/lib/libboost_program_options.a + LIBS += $$UPNPROOT/lib/libminiupnpc.a +} + android { message("Using Android settings") DEFINES += ANDROID=1 From 05c2adeefd12111a9b935df8c86c5ca449e144ac Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Mon, 18 Sep 2017 15:24:53 -0400 Subject: [PATCH 48/81] fix typo --- build/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 06e1c24f..d966ab2f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -393,7 +393,7 @@ message(STATUS " UPnP : ${WITH_UPNP}") message(STATUS " PCH : ${WITH_PCH}") message(STATUS " MESHNET : ${WITH_MESHNET}") message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}") -message(STATUS " THEADSANITIZER : ${WITH_THREADSANITIZER}") +message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}") message(STATUS " I2LUA : ${WITH_I2LUA}") message(STATUS " WEBSOCKETS : ${WITH_WEBSOCKETS}") message(STATUS "---------------------------------------") From d500fe66fd572899c4b4a99bc577d63c1b538ff5 Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Mon, 18 Sep 2017 18:49:03 -0400 Subject: [PATCH 49/81] Add option logclftime=true for writing full date and time to logs --- libi2pd/Config.cpp | 1 + libi2pd/Log.cpp | 7 +++++-- libi2pd/Log.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index f8985010..26f09696 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -38,6 +38,7 @@ namespace config { ("log", value()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)") ("logfile", value()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)") ("loglevel", value()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)") + ("logclftime", value()->default_value(false), "Write full CLF-formatted date and time to log (default: write only time)") ("family", value()->default_value(""), "Specify a family, router belongs to") ("datadir", value()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)") ("host", value()->default_value("0.0.0.0"), "External IP") diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 7cd4205e..0430ed57 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -7,6 +7,7 @@ */ #include "Log.h" +#include "Config.h" namespace i2p { namespace log { @@ -58,7 +59,7 @@ namespace log { Log::Log(): m_Destination(eLogStdout), m_MinLevel(eLogInfo), - m_LogStream (nullptr), m_Logfile(""), m_HasColors(true), + m_LogStream (nullptr), m_Logfile(""), m_HasColors(true), m_TimeFormat("%H:%M:%S"), m_IsRunning (false), m_Thread (nullptr) { } @@ -73,6 +74,8 @@ namespace log { if (!m_IsRunning) { m_IsRunning = true; + bool logclftime; i2p::config::GetOption("logclftime", logclftime); + if (logclftime) m_TimeFormat = "[%d/%b/%Y:%H:%M:%S %z]"; m_Thread = new std::thread (std::bind (&Log::Run, this)); } } @@ -118,7 +121,7 @@ namespace log { const char * Log::TimeAsString(std::time_t t) { if (t != m_LastTimestamp) { - strftime(m_LastDateTime, sizeof(m_LastDateTime), "%H:%M:%S", localtime(&t)); + strftime(m_LastDateTime, sizeof(m_LastDateTime), m_TimeFormat.c_str(), localtime(&t)); m_LastTimestamp = t; } return m_LastDateTime; diff --git a/libi2pd/Log.h b/libi2pd/Log.h index 1d02a845..e3ce65cd 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -58,6 +58,7 @@ namespace log { char m_LastDateTime[64]; i2p::util::Queue > m_Queue; bool m_HasColors; + std::string m_TimeFormat; volatile bool m_IsRunning; std::thread * m_Thread; From 681810ea38181eb81bcd12f182aa257736c709bd Mon Sep 17 00:00:00 2001 From: Darknet Villain Date: Tue, 19 Sep 2017 19:46:28 -0400 Subject: [PATCH 50/81] Use setter method for m_TimeFormat, set time format in Daemon.cpp instead of Log.cpp --- daemon/Daemon.cpp | 4 ++++ libi2pd/Log.cpp | 3 --- libi2pd/Log.h | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index 32595390..658bf011 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -94,8 +94,12 @@ namespace i2p std::string logs = ""; i2p::config::GetOption("log", logs); std::string logfile = ""; i2p::config::GetOption("logfile", logfile); std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel); + bool logclftime; i2p::config::GetOption("logclftime", logclftime); /* setup logging */ + if (logclftime) + i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]"); + if (isDaemon && (logs == "" || logs == "stdout")) logs = "file"; diff --git a/libi2pd/Log.cpp b/libi2pd/Log.cpp index 0430ed57..8ae417c2 100644 --- a/libi2pd/Log.cpp +++ b/libi2pd/Log.cpp @@ -7,7 +7,6 @@ */ #include "Log.h" -#include "Config.h" namespace i2p { namespace log { @@ -74,8 +73,6 @@ namespace log { if (!m_IsRunning) { m_IsRunning = true; - bool logclftime; i2p::config::GetOption("logclftime", logclftime); - if (logclftime) m_TimeFormat = "[%d/%b/%Y:%H:%M:%S %z]"; m_Thread = new std::thread (std::bind (&Log::Run, this)); } } diff --git a/libi2pd/Log.h b/libi2pd/Log.h index e3ce65cd..bec741a8 100644 --- a/libi2pd/Log.h +++ b/libi2pd/Log.h @@ -108,6 +108,12 @@ namespace log { */ void SendTo (std::shared_ptr os); + /** + * @brief Sets format for timestamps in log + * @param format String with timestamp format + */ + void SetTimeFormat (std::string format) { m_TimeFormat = format; }; + #ifndef _WIN32 /** * @brief Sets log destination to syslog From 94bba69dee2b17c0ec1ceaf5d17095bbaac765c3 Mon Sep 17 00:00:00 2001 From: redfish Date: Tue, 26 Sep 2017 10:55:13 -0400 Subject: [PATCH 51/81] cmake: check openssl version See #835 for memory leak issues with OpenSSL >= 1.1 --- build/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index d966ab2f..230464d0 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -322,6 +322,10 @@ endif() find_package ( OpenSSL REQUIRED ) if(NOT DEFINED OPENSSL_INCLUDE_DIR) message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!") +else() + if(NOT (OPENSSL_VERSION VERSION_LESS 1.1)) + message(SEND_ERROR "Unsupported OpenSSL version: ${OPENSSL_VERSION} (required < 1.1)") + endif() endif() if (WITH_UPNP) From 8179e7dbf82630bd9834299ba078990a3ce9fb3c Mon Sep 17 00:00:00 2001 From: redfish Date: Tue, 26 Sep 2017 20:46:06 -0400 Subject: [PATCH 52/81] cmake: issue a non-fatal warning for openssl >=1.1 --- build/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 230464d0..6b0c0cf3 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -324,7 +324,7 @@ if(NOT DEFINED OPENSSL_INCLUDE_DIR) message(SEND_ERROR "Could not find OpenSSL. Please download and install it first!") else() if(NOT (OPENSSL_VERSION VERSION_LESS 1.1)) - message(SEND_ERROR "Unsupported OpenSSL version: ${OPENSSL_VERSION} (required < 1.1)") + message(WARNING "Your OpenSSL version ${OPENSSL_VERSION} >=1.1 is experimental: build with v1.0 when possible.") endif() endif() From c0bcab8bc51209eb49b4cb92a5301c35160af206 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 27 Sep 2017 09:05:52 -0400 Subject: [PATCH 53/81] try fixing leak --- libi2pd/Signature.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 12ee6c2c..7a84a41b 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -316,7 +316,6 @@ namespace crypto bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const { - BN_CTX_start (ctx); BIGNUM * x2 = BN_CTX_get (ctx), * y2 = BN_CTX_get (ctx), * tmp = BN_CTX_get (ctx); BN_sqr (x2, p.x, ctx); // x^2 BN_sqr (y2, p.y, ctx); // y^2 @@ -353,6 +352,7 @@ namespace crypto BN_mod_mul (x, x, I, q, ctx); if (BN_is_odd (x)) BN_sub (x, q, x); + return x; } @@ -370,7 +370,7 @@ namespace crypto buf1[0] &= 0x7f; // clear highest bit BIGNUM * y = BN_new (); BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y); - auto x = RecoverX (y, ctx); + BIGNUM * x = RecoverX (y, ctx); if (BN_is_bit_set (x, 0) != isHighestBitSet) BN_sub (x, q, x); // x = q - x BIGNUM * z = BN_new (), * t = BN_new (); From 7fb2d13a8bb10d00f385366c65a7c0a087455d9a Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 27 Sep 2017 09:49:43 -0400 Subject: [PATCH 54/81] use BN_CTX_start and BN_CTX_end instead of removing BN_CTX_start --- libi2pd/Signature.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index 7a84a41b..c5c2419b 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -316,6 +316,7 @@ namespace crypto bool IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const { + BN_CTX_start (ctx); BIGNUM * x2 = BN_CTX_get (ctx), * y2 = BN_CTX_get (ctx), * tmp = BN_CTX_get (ctx); BN_sqr (x2, p.x, ctx); // x^2 BN_sqr (y2, p.y, ctx); // y^2 @@ -352,7 +353,7 @@ namespace crypto BN_mod_mul (x, x, I, q, ctx); if (BN_is_odd (x)) BN_sub (x, q, x); - + BN_CTX_end (ctx); return x; } From dd4f066e95c7120595cc393130865d62a057d4eb Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 27 Sep 2017 23:28:58 +0300 Subject: [PATCH 55/81] add graceful shutdown in webconsole for windows add stop graceful shutdown menu item add reload menu item --- Win32/DaemonWin32.cpp | 152 ++++++++++++++++---------------- Win32/Win32App.cpp | 40 ++++++++- Win32/Win32App.h | 9 +- daemon/Daemon.h | 72 +++++++-------- daemon/HTTPServer.cpp | 199 +++++++++++++++++++++--------------------- 5 files changed, 255 insertions(+), 217 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index 698cf390..d36949c3 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -14,99 +14,99 @@ namespace i2p { - namespace util +namespace util +{ + bool DaemonWin32::init(int argc, char* argv[]) { - bool DaemonWin32::init(int argc, char* argv[]) + setlocale(LC_CTYPE, ""); + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + setlocale(LC_ALL, "Russian"); + + if (!Daemon_Singleton::init(argc, argv)) + return false; + + std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl); + if (serviceControl == "install") { - setlocale(LC_CTYPE, ""); - SetConsoleCP(1251); - SetConsoleOutputCP(1251); - setlocale(LC_ALL, "Russian"); - - if (!Daemon_Singleton::init(argc, argv)) - return false; - - std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl); - if (serviceControl == "install") - { - LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service"); - InstallService( - SERVICE_NAME, // Name of service - SERVICE_DISPLAY_NAME, // Name to display - SERVICE_START_TYPE, // Service start type - SERVICE_DEPENDENCIES, // Dependencies - SERVICE_ACCOUNT, // Service running account - SERVICE_PASSWORD // Password of the account - ); - return false; - } - else if (serviceControl == "remove") - { - LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service"); - UninstallService(SERVICE_NAME); - return false; - } - - if (isDaemon) - { - LogPrint(eLogDebug, "Daemon: running as service"); - I2PService service(SERVICE_NAME); - if (!I2PService::Run(service)) - { - LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); - return false; - } - return false; - } - else - LogPrint(eLogDebug, "Daemon: running as user"); - return true; + LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service"); + InstallService( + SERVICE_NAME, // Name of service + SERVICE_DISPLAY_NAME, // Name to display + SERVICE_START_TYPE, // Service start type + SERVICE_DEPENDENCIES, // Dependencies + SERVICE_ACCOUNT, // Service running account + SERVICE_PASSWORD // Password of the account + ); + return false; + } + else if (serviceControl == "remove") + { + LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service"); + UninstallService(SERVICE_NAME); + return false; } - bool DaemonWin32::start() + if (isDaemon) { - setlocale(LC_CTYPE, ""); - SetConsoleCP(1251); - SetConsoleOutputCP(1251); - setlocale(LC_ALL, "Russian"); -#ifdef WIN32_APP - if (!i2p::win32::StartWin32App ()) return false; + LogPrint(eLogDebug, "Daemon: running as service"); + I2PService service(SERVICE_NAME); + if (!I2PService::Run(service)) + { + LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); + return false; + } + return false; + } + else + LogPrint(eLogDebug, "Daemon: running as user"); + return true; + } - // override log - i2p::config::SetOption("log", std::string ("file")); + bool DaemonWin32::start() + { + setlocale(LC_CTYPE, ""); + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + setlocale(LC_ALL, "Russian"); +#ifdef WIN32_APP + if (!i2p::win32::StartWin32App ()) return false; + + // override log + i2p::config::SetOption("log", std::string ("file")); #endif - bool ret = Daemon_Singleton::start(); - if (ret && i2p::log::Logger().GetLogType() == eLogFile) - { - // TODO: find out where this garbage to console comes from - SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); - SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); - } - bool insomnia; i2p::config::GetOption("insomnia", insomnia); - if (insomnia) - SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); - return ret; - } - - bool DaemonWin32::stop() + bool ret = Daemon_Singleton::start(); + if (ret && i2p::log::Logger().GetLogType() == eLogFile) { + // TODO: find out where this garbage to console comes from + SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); + SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); + } + bool insomnia; i2p::config::GetOption("insomnia", insomnia); + if (insomnia) + SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); + return ret; + } + + bool DaemonWin32::stop() + { #ifdef WIN32_APP - i2p::win32::StopWin32App (); + i2p::win32::StopWin32App (); #endif - return Daemon_Singleton::stop(); - } + return Daemon_Singleton::stop(); + } - void DaemonWin32::run () - { + void DaemonWin32::run () + { #ifdef WIN32_APP - i2p::win32::RunWin32App (); + i2p::win32::RunWin32App (); #else - while (running) + while (running) { std::this_thread::sleep_for (std::chrono::seconds(1)); } #endif - } } } +} #endif diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index e66b5f08..4c7eae03 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -9,6 +9,7 @@ #include "Tunnel.h" #include "version.h" #include "resource.h" +#include "Daemon.h" #include "Win32App.h" #include @@ -21,6 +22,8 @@ #define ID_CONSOLE 2002 #define ID_APP 2003 #define ID_GRACEFUL_SHUTDOWN 2004 +#define ID_STOP_GRACEFUL_SHUTDOWN 2005 +#define ID_RELOAD 2006 #define ID_TRAY_ICON 2050 #define WM_TRAYICON (WM_USER + 1) @@ -39,7 +42,11 @@ namespace win32 InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About..."); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); - InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_RELOAD, "&Reload configs"); + if (!i2p::util::DaemonWin32::Instance ().isGraceful) + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_GRACEFUL_SHUTDOWN, "&Graceful shutdown"); + else + InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_STOP_GRACEFUL_SHUTDOWN, "&Stop graceful shutdown"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit"); SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE); SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); @@ -68,7 +75,7 @@ namespace win32 nid.uCallbackMessage = WM_TRAYICON; nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON)); strcpy (nid.szTip, "i2pd"); - strcpy (nid.szInfo, "i2pd is running"); + strcpy (nid.szInfo, "i2pd is starting"); Shell_NotifyIcon(NIM_ADD, &nid ); } @@ -120,6 +127,7 @@ namespace win32 static void PrintMainWindowText (std::stringstream& s) { + s << "\n"; s << "Status: "; switch (i2p::context.GetStatus()) { @@ -153,6 +161,7 @@ namespace win32 s << "In: " << i2p::tunnel::tunnels.CountInboundTunnels() << "; "; s << "Out: " << i2p::tunnel::tunnels.CountOutboundTunnels() << "; "; s << "Transit: " << i2p::tunnel::tunnels.CountTransitTunnels() << "\n"; + s << "\n"; } static LRESULT CALLBACK WndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -192,6 +201,22 @@ namespace win32 { i2p::context.SetAcceptsTunnels (false); SetTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER, 10*60*1000, nullptr); // 10 minutes + i2p::util::DaemonWin32::Instance ().isGraceful = true; + return 0; + } + case ID_STOP_GRACEFUL_SHUTDOWN: + { + i2p::context.SetAcceptsTunnels (true); + KillTimer (hWnd, IDT_GRACEFUL_SHUTDOWN_TIMER); + i2p::util::DaemonWin32::Instance ().isGraceful = false; + return 0; + } + case ID_RELOAD: + { + i2p::client::context.ReloadConfig(); + std::stringstream text; + text << "I2Pd reloading configs..."; + MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK ); return 0; } case ID_CONSOLE: @@ -322,7 +347,7 @@ namespace win32 wclx.lpszClassName = I2PD_WIN32_CLASSNAME; RegisterClassEx (&wclx); // create new window - if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 180, NULL, NULL, hInst, NULL)) + if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 100, 100, 350, 210, NULL, NULL, hInst, NULL)) { MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); return false; @@ -353,5 +378,14 @@ namespace win32 PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_GRACEFUL_SHUTDOWN, 0), 0); return hWnd; } + + bool StopGracefulShutdown () + { + HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); + if (hWnd) + PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_STOP_GRACEFUL_SHUTDOWN, 0), 0); + return hWnd; + } + } } diff --git a/Win32/Win32App.h b/Win32/Win32App.h index 3babffa9..b230eb06 100644 --- a/Win32/Win32App.h +++ b/Win32/Win32App.h @@ -7,10 +7,11 @@ namespace i2p { namespace win32 { - bool StartWin32App (); - void StopWin32App (); - int RunWin32App (); - bool GracefulShutdown (); + bool StartWin32App (); + void StopWin32App (); + int RunWin32App (); + bool GracefulShutdown (); + bool StopGracefulShutdown (); } } #endif // WIN32APP_H__ diff --git a/daemon/Daemon.h b/daemon/Daemon.h index 2bc05462..48301e73 100644 --- a/daemon/Daemon.h +++ b/daemon/Daemon.h @@ -6,11 +6,11 @@ namespace i2p { - namespace util +namespace util +{ + class Daemon_Singleton_Private; + class Daemon_Singleton { - class Daemon_Singleton_Private; - class Daemon_Singleton - { public: virtual bool init(int argc, char* argv[]); virtual bool start(); @@ -29,40 +29,38 @@ namespace i2p // d-pointer for httpServer, httpProxy, etc. class Daemon_Singleton_Private; Daemon_Singleton_Private &d; - }; + }; #if defined(QT_GUI_LIB) // check if QT #define Daemon i2p::util::DaemonQT::Instance() - // dummy, invoked from RunQT - class DaemonQT: public i2p::util::Daemon_Singleton + // dummy, invoked from RunQT + class DaemonQT: public i2p::util::Daemon_Singleton { public: - static DaemonQT& Instance() { static DaemonQT instance; return instance; } - }; + }; #elif defined(ANDROID) #define Daemon i2p::util::DaemonAndroid::Instance() // dummy, invoked from android/jni/DaemonAndroid.* - class DaemonAndroid: public i2p::util::Daemon_Singleton + class DaemonAndroid: public i2p::util::Daemon_Singleton { public: - static DaemonAndroid& Instance() { static DaemonAndroid instance; return instance; } - }; + }; #elif defined(_WIN32) #define Daemon i2p::util::DaemonWin32::Instance() - class DaemonWin32 : public Daemon_Singleton - { + class DaemonWin32 : public Daemon_Singleton + { public: static DaemonWin32& Instance() { @@ -74,34 +72,36 @@ namespace i2p bool start(); bool stop(); void run (); - }; + + bool isGraceful; + + DaemonWin32 ():isGraceful(false) {} + }; + #else #define Daemon i2p::util::DaemonLinux::Instance() - class DaemonLinux : public Daemon_Singleton - { - public: - static DaemonLinux& Instance() - { - static DaemonLinux instance; - return instance; - } + class DaemonLinux : public Daemon_Singleton + { + public: + static DaemonLinux& Instance() + { + static DaemonLinux instance; + return instance; + } - bool start(); - bool stop(); - void run (); + bool start(); + bool stop(); + void run (); - private: + private: + std::string pidfile; + int pidFH; - std::string pidfile; - int pidFH; - - public: - - int gracefulShutdownInterval; // in seconds - - }; + public: + int gracefulShutdownInterval; // in seconds + }; #endif - } +} } #endif // DAEMON_H__ diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index f3f9bb74..d6a358cf 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -58,9 +58,9 @@ namespace http { " .left { float: left; position: absolute; }\r\n" " .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; }\r\n" - " .tunnel.expiring { color: #D3AE3F; }\r\n" - " .tunnel.failed { color: #D33F3F; }\r\n" - " .tunnel.another { color: #434343; }\r\n" + " .tunnel.expiring { color: #D3AE3F; }\r\n" + " .tunnel.failed { color: #D33F3F; }\r\n" + " .tunnel.another { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" " .private { background: black; color: black; } .private:hover { background: black; color: white } \r\n" @@ -89,7 +89,7 @@ namespace http { const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; - static void ShowUptime (std::stringstream& s, int seconds) + static void ShowUptime (std::stringstream& s, int seconds) { int num; @@ -125,11 +125,11 @@ namespace http { std::string state; switch (eState) { case i2p::tunnel::eTunnelStateBuildReplyReceived : - case i2p::tunnel::eTunnelStatePending : state = "building"; break; + case i2p::tunnel::eTunnelStatePending : state = "building"; break; case i2p::tunnel::eTunnelStateBuildFailed : case i2p::tunnel::eTunnelStateTestFailed : - case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; - case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; + case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; + case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; case i2p::tunnel::eTunnelStateEstablished : state = "established"; break; default: state = "unknown"; break; } @@ -185,7 +185,7 @@ namespace http { s << "ERROR: " << string << "
\r\n"; } - void ShowStatus (std::stringstream& s, bool includeHiddenContent) + void ShowStatus (std::stringstream& s, bool includeHiddenContent) { s << "Uptime: "; ShowUptime(s, i2p::context.GetUptime ()); @@ -195,21 +195,21 @@ namespace http { { case eRouterStatusOK: s << "OK"; break; case eRouterStatusTesting: s << "Testing"; break; - case eRouterStatusFirewalled: s << "Firewalled"; break; - case eRouterStatusError: - { - s << "Error"; + case eRouterStatusFirewalled: s << "Firewalled"; break; + case eRouterStatusError: + { + s << "Error"; switch (i2p::context.GetError ()) { case eRouterErrorClockSkew: - s << "
Clock skew"; + s << "
Clock skew"; break; - default: ; - } + default: ; + } break; - } + } default: s << "Unknown"; - } + } s << "
\r\n"; #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) if (auto remains = Daemon.gracefulShutdownInterval) { @@ -230,38 +230,38 @@ namespace http { s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)
\r\n"; s << "Transit: "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; + s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n"; s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n"; s << "
\r\n\r\n

\r\n"; - if(includeHiddenContent) { - s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; - s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; - s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; - s << "Our external address:" << "
\r\n" ; - for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) - { - switch (address->transportStyle) - { - case i2p::data::RouterInfo::eTransportNTCP: - if (address->host.is_v6 ()) - s << "NTCP6  "; - else - s << "NTCP  "; - break; - case i2p::data::RouterInfo::eTransportSSU: - if (address->host.is_v6 ()) - s << "SSU6     "; - else - s << "SSU     "; - break; - default: - s << "Unknown  "; - } - s << address->host.to_string() << ":" << address->port << "
\r\n"; - } - } - s << "

\r\n
\r\n"; - s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; + if(includeHiddenContent) { + s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; + s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; + s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; + s << "Our external address:" << "
\r\n" ; + for (const auto& address : i2p::context.GetRouterInfo().GetAddresses()) + { + switch (address->transportStyle) + { + case i2p::data::RouterInfo::eTransportNTCP: + if (address->host.is_v6 ()) + s << "NTCP6  "; + else + s << "NTCP  "; + break; + case i2p::data::RouterInfo::eTransportSSU: + if (address->host.is_v6 ()) + s << "SSU6     "; + else + s << "SSU     "; + break; + default: + s << "Unknown  "; + } + s << address->host.to_string() << ":" << address->port << "
\r\n"; + } + } + s << "

\r\n\r\n"; + s << "Routers: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; @@ -273,13 +273,13 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } - void ShowLocalDestinations (std::stringstream& s) + void ShowLocalDestinations (std::stringstream& s) { s << "Local Destinations:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetDestinations ()) { - auto ident = it.second->GetIdentHash (); - s << ""; + auto ident = it.second->GetIdentHash (); + s << ""; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; } @@ -291,11 +291,11 @@ namespace http { { auto dest = it.second->GetDestination (); if (dest) - { - auto ident = dest->GetIdentHash (); - s << ""; + { + auto ident = dest->GetIdentHash (); + s << ""; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; - } + } } } } @@ -341,7 +341,7 @@ namespace http { s << "
" << std::endl; } - void ShowLocalDestination (std::stringstream& s, const std::string& b32) + void ShowLocalDestination (std::stringstream& s, const std::string& b32) { s << "Local Destination:
\r\n
\r\n"; i2p::data::IdentHash ident; @@ -349,7 +349,7 @@ namespace http { auto dest = i2p::client::context.FindLocalDestination (ident); if (dest) { - ShowLeaseSetDestination (s, dest); + ShowLeaseSetDestination (s, dest); // show streams s << "
\r\n"; s << ""; @@ -377,35 +377,35 @@ namespace http { s << ""; s << ""; s << ""; - s << "
\r\n" << std::endl; - } + s << "
\r\n" << std::endl; + } s << "
Streams
StreamID" << it->GetRTT () << "" << it->GetWindowSize () << "" << (int)it->GetStatus () << "
"; } } - static void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id) + static void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id) { auto i2cpServer = i2p::client::context.GetI2CPServer (); if (i2cpServer) { s << "I2CP Local Destination:
\r\n
\r\n"; - auto it = i2cpServer->GetSessions ().find (std::stoi (id)); + auto it = i2cpServer->GetSessions ().find (std::stoi (id)); if (it != i2cpServer->GetSessions ().end ()) ShowLeaseSetDestination (s, it->second->GetDestination ()); else - ShowError(s, "I2CP session not found"); + ShowError(s, "I2CP session not found"); } else ShowError(s, "I2CP is not enabled"); } - void ShowLeasesSets(std::stringstream& s) + void ShowLeasesSets(std::stringstream& s) { s << "
LeaseSets (click on to show info):

\r\n"; int counter = 1; // for each lease set i2p::data::netdb.VisitLeaseSets( - [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) + [&s, &counter](const i2p::data::IdentHash dest, std::shared_ptr leaseSet) { // create copy of lease set so we extract leases i2p::data::LeaseSet ls(leaseSet->GetBuffer(), leaseSet->GetBufferLen()); @@ -432,7 +432,7 @@ namespace http { // end for each lease set } - void ShowTunnels (std::stringstream& s) + void ShowTunnels (std::stringstream& s) { s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; @@ -454,7 +454,7 @@ namespace http { s << "
\r\n"; } - static void ShowCommands (std::stringstream& s, uint32_t token) + static void ShowCommands (std::stringstream& s, uint32_t token) { /* commands */ s << "Router Commands
\r\n"; @@ -465,18 +465,20 @@ namespace http { else s << " Accept transit tunnels
\r\n"; #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) - if (Daemon.gracefulShutdownInterval) + if (Daemon.gracefulShutdownInterval) s << " Cancel graceful shutdown
"; - else + else s << " Start graceful shutdown
\r\n"; -#endif -#ifdef WIN32_APP - s << " Graceful shutdown
\r\n"; +#elif defined(WIN32_APP) + if (i2p::util::DaemonWin32::Instance().isGraceful) + s << " Cancel graceful shutdown
"; + else + s << " Graceful shutdown
\r\n"; #endif s << " Force shutdown
\r\n"; } - void ShowTransitTunnels (std::stringstream& s) + void ShowTransitTunnels (std::stringstream& s) { s << "Transit tunnels:
\r\n
\r\n"; for (const auto& it: i2p::tunnel::tunnels.GetTransitTunnels ()) @@ -491,10 +493,10 @@ namespace http { } } - void ShowTransports (std::stringstream& s) + void ShowTransports (std::stringstream& s) { s << "Transports:
\r\n
\r\n"; - auto ntcpServer = i2p::transport::transports.GetNTCPServer (); + auto ntcpServer = i2p::transport::transports.GetNTCPServer (); if (ntcpServer) { auto sessions = ntcpServer->GetNTCPSessions (); @@ -577,7 +579,7 @@ namespace http { } } - void ShowSAMSessions (std::stringstream& s) + void ShowSAMSessions (std::stringstream& s) { auto sam = i2p::client::context.GetSAMBridge (); if (!sam) { @@ -624,13 +626,13 @@ namespace http { } } - void ShowI2PTunnels (std::stringstream& s) + void ShowI2PTunnels (std::stringstream& s) { s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; @@ -639,16 +641,16 @@ namespace http { if (httpProxy) { auto& ident = httpProxy->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << "HTTP Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; - } + } auto socksProxy = i2p::client::context.GetSocksProxy (); if (socksProxy) { auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << "SOCKS Proxy" << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; @@ -659,7 +661,7 @@ namespace http { for (auto& it: serverTunnels) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); @@ -673,7 +675,7 @@ namespace http { for (auto& it: clientForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; @@ -686,7 +688,7 @@ namespace http { for (auto& it: serverForwards) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; @@ -756,10 +758,10 @@ namespace http { } /* method #2: 'Authorization' header sent */ auto provided = req.GetHeader ("Authorization"); - if (provided.length () > 0) - { + if (provided.length () > 0) + { bool result = false; - + std::string expected = user + ":" + pass; size_t b64_sz = i2p::data::Base64EncodingBufferSize(expected.length()) + 1; char * b64_creds = new char[b64_sz]; @@ -802,7 +804,7 @@ namespace http { } else if (req.uri.find("cmd=") != std::string::npos) { HandleCommand (req, res, s); } else { - ShowStatus (s, true); + ShowStatus (s, true); res.add_header("Refresh", "10"); } ShowPageTail (s); @@ -814,7 +816,7 @@ namespace http { std::map HTTPConnection::m_Tokens; void HTTPConnection::HandlePage (const HTTPReq& req, HTTPRes& res, std::stringstream& s) - { + { std::map params; std::string page(""); URL url; @@ -840,13 +842,13 @@ namespace http { else ++it; } - m_Tokens[token] = ts; + m_Tokens[token] = ts; ShowCommands (s, token); } else if (page == HTTP_PAGE_TRANSIT_TUNNELS) ShowTransitTunnels (s); else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) - ShowLocalDestinations (s); + ShowLocalDestinations (s); else if (page == HTTP_PAGE_LOCAL_DESTINATION) ShowLocalDestination (s, params["b32"]); else if (page == HTTP_PAGE_I2CP_LOCAL_DESTINATION) @@ -864,7 +866,7 @@ namespace http { ShowError(s, "Unknown page: " + page); return; } - } + } void HTTPConnection::HandleCommand (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { @@ -881,7 +883,7 @@ namespace http { return; } - std::string cmd = params["cmd"]; + std::string cmd = params["cmd"]; if (cmd == HTTP_COMMAND_RUN_PEER_TEST) i2p::transport::transports.PeerTest (); else if (cmd == HTTP_COMMAND_RELOAD_CONFIG) @@ -894,14 +896,15 @@ namespace http { i2p::context.SetAcceptsTunnels (false); #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) Daemon.gracefulShutdownInterval = 10*60; -#endif -#ifdef WIN32_APP +#elif defined(WIN32_APP) i2p::win32::GracefulShutdown (); #endif } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { i2p::context.SetAcceptsTunnels (true); #if (!defined(WIN32) && !defined(QT_GUI_LIB) && !defined(ANDROID)) Daemon.gracefulShutdownInterval = 0; +#elif defined(WIN32_APP) + i2p::win32::StopGracefulShutdown (); #endif } else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) { Daemon.running = false; @@ -940,7 +943,7 @@ namespace http { void HTTPServer::Start () { - bool needAuth; i2p::config::GetOption("http.auth", needAuth); + bool needAuth; i2p::config::GetOption("http.auth", needAuth); std::string user; i2p::config::GetOption("http.user", user); std::string pass; i2p::config::GetOption("http.pass", pass); /* generate pass if needed */ @@ -968,7 +971,7 @@ namespace http { m_IsRunning = false; m_Acceptor.close(); m_Service.stop (); - if (m_Thread) + if (m_Thread) { m_Thread->join (); m_Thread = nullptr; @@ -986,7 +989,7 @@ namespace http { catch (std::exception& ex) { LogPrint (eLogError, "HTTPServer: runtime exception: ", ex.what ()); - } + } } } @@ -997,7 +1000,7 @@ namespace http { boost::asio::placeholders::error, newSocket)); } - void HTTPServer::HandleAccept(const boost::system::error_code& ecode, + void HTTPServer::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr newSocket) { if (ecode) @@ -1005,7 +1008,7 @@ namespace http { if(newSocket) newSocket->close(); LogPrint(eLogError, "HTTP Server: error handling accept ", ecode.message()); if(ecode != boost::asio::error::operation_aborted) - Accept(); + Accept(); return; } CreateConnection(newSocket); From 1d8a481d596c975821248a09d2a46658e241a2ae Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 27 Sep 2017 23:41:34 +0300 Subject: [PATCH 56/81] fix tabulation --- daemon/HTTPServer.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index d6a358cf..99ed0441 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -58,9 +58,9 @@ namespace http { " .left { float: left; position: absolute; }\r\n" " .right { float: left; font-size: 1em; margin-left: 13em; max-width: 46em; overflow: auto; }\r\n" " .tunnel.established { color: #56B734; }\r\n" - " .tunnel.expiring { color: #D3AE3F; }\r\n" - " .tunnel.failed { color: #D33F3F; }\r\n" - " .tunnel.another { color: #434343; }\r\n" + " .tunnel.expiring { color: #D3AE3F; }\r\n" + " .tunnel.failed { color: #D33F3F; }\r\n" + " .tunnel.another { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" " .private { background: black; color: black; } .private:hover { background: black; color: white } \r\n" @@ -83,7 +83,7 @@ namespace http { const char HTTP_COMMAND_DISABLE_TRANSIT[] = "disable_transit"; const char HTTP_COMMAND_SHUTDOWN_START[] = "shutdown_start"; const char HTTP_COMMAND_SHUTDOWN_CANCEL[] = "shutdown_cancel"; - const char HTTP_COMMAND_SHUTDOWN_NOW[] = "terminate"; + const char HTTP_COMMAND_SHUTDOWN_NOW[] = "terminate"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; const char HTTP_COMMAND_RELOAD_CONFIG[] = "reload_config"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; @@ -125,11 +125,11 @@ namespace http { std::string state; switch (eState) { case i2p::tunnel::eTunnelStateBuildReplyReceived : - case i2p::tunnel::eTunnelStatePending : state = "building"; break; + case i2p::tunnel::eTunnelStatePending : state = "building"; break; case i2p::tunnel::eTunnelStateBuildFailed : case i2p::tunnel::eTunnelStateTestFailed : - case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; - case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; + case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; + case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; case i2p::tunnel::eTunnelStateEstablished : state = "established"; break; default: state = "unknown"; break; } @@ -943,7 +943,7 @@ namespace http { void HTTPServer::Start () { - bool needAuth; i2p::config::GetOption("http.auth", needAuth); + bool needAuth; i2p::config::GetOption("http.auth", needAuth); std::string user; i2p::config::GetOption("http.user", user); std::string pass; i2p::config::GetOption("http.pass", pass); /* generate pass if needed */ From 8c8127dda6881fac62f7e167a5d6f68c68359392 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Fri, 29 Sep 2017 00:03:07 +0300 Subject: [PATCH 57/81] fixed perfect forwarding for the memory pool --- libi2pd/Streaming.h | 4 ++-- libi2pd/util.h | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index c598245a..eae959ed 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -276,8 +276,8 @@ namespace stream /** set max connections per minute per destination */ void SetMaxConnsPerMinute(const uint32_t conns); - Packet * NewPacket () { return m_PacketsPool.Acquire (); }; - void DeletePacket (Packet * p) { if (p) m_PacketsPool.Release (p); }; + Packet * NewPacket () { return m_PacketsPool.Acquire (); } + void DeletePacket (Packet * p) { m_PacketsPool.Release (p); } private: diff --git a/libi2pd/util.h b/libi2pd/util.h index 38ca6b28..1a9b9a73 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #ifdef ANDROID @@ -14,7 +15,7 @@ namespace std template std::string to_string(T value) { - return boost::lexical_cast(value); + return boost::lexical_cast(value); } inline int stoi(const std::string& str) @@ -29,12 +30,12 @@ namespace i2p namespace util { - template + template class MemoryPool { public: - MemoryPool (): m_Head (nullptr) {}; + MemoryPool (): m_Head (nullptr) {} ~MemoryPool () { while (m_Head) @@ -48,12 +49,12 @@ namespace util template T * Acquire (TArgs&&... args) { - if (!m_Head) return new T(args...); + if (!m_Head) return new T(std::forward(args)...); else { auto tmp = m_Head; m_Head = static_cast(*(void * *)m_Head); // next - return new (tmp)T(args...); + return new (tmp)T(std::forward(args)...); } } @@ -68,14 +69,15 @@ namespace util template std::unique_ptr > AcquireUnique (TArgs&&... args) { - return std::unique_ptr >(Acquire (args...), + return std::unique_ptr >(Acquire (std::forward(args)...), std::bind (&MemoryPool::Release, this, std::placeholders::_1)); } template std::shared_ptr AcquireShared (TArgs&&... args) { - return std::shared_ptr(Acquire (args...), std::bind (&MemoryPool::Release, this, std::placeholders::_1)); + return std::shared_ptr(Acquire (std::forward(args)...), + std::bind (&MemoryPool::Release, this, std::placeholders::_1)); } protected: @@ -88,13 +90,13 @@ namespace util { public: - MemoryPoolMt () {}; + MemoryPoolMt () {} template T * AcquireMt (TArgs&&... args) { - if (!this->m_Head) return new T(args...); + if (!this->m_Head) return new T(std::forward(args)...); std::lock_guard l(m_Mutex); - return this->Acquire (args...); + return this->Acquire (std::forward(args)...); } void ReleaseMt (T * t) From 8e3c9410dcf51fcf1ee75401f1a3f797c8fdf7c9 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Fri, 29 Sep 2017 00:48:14 +0300 Subject: [PATCH 58/81] missed self assigment check for EDDSAPoint --- libi2pd/Signature.h | 46 ++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index b85ef4cf..531fdfdf 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -363,31 +363,43 @@ namespace crypto // EdDSA struct EDDSAPoint { - BIGNUM * x, * y; - BIGNUM * z, * t; // projective coordinates - EDDSAPoint (): x(nullptr), y(nullptr), z(nullptr), t(nullptr) {}; - EDDSAPoint (const EDDSAPoint& other): x(nullptr), y(nullptr), z(nullptr), t(nullptr) - { *this = other; }; - EDDSAPoint (EDDSAPoint&& other): x(nullptr), y(nullptr), z(nullptr), t(nullptr) - { *this = std::move (other); }; - EDDSAPoint (BIGNUM * x1, BIGNUM * y1, BIGNUM * z1 = nullptr, BIGNUM * t1 = nullptr): x(x1), y(y1), z(z1), t(t1) {}; - ~EDDSAPoint () { BN_free (x); BN_free (y); BN_free(z); BN_free(t); }; + BIGNUM * x {nullptr}; + BIGNUM * y {nullptr}; + BIGNUM * z {nullptr}; + BIGNUM * t {nullptr}; // projective coordinates + + EDDSAPoint () {} + EDDSAPoint (const EDDSAPoint& other) { *this = other; } + EDDSAPoint (EDDSAPoint&& other) { *this = std::move (other); } + EDDSAPoint (BIGNUM * x1, BIGNUM * y1, BIGNUM * z1 = nullptr, BIGNUM * t1 = nullptr) + : x(x1) + , y(y1) + , z(z1) + , t(t1) + {} + ~EDDSAPoint () { BN_free (x); BN_free (y); BN_free(z); BN_free(t); } EDDSAPoint& operator=(EDDSAPoint&& other) { - if (x) BN_free (x); x = other.x; other.x = nullptr; - if (y) BN_free (y); y = other.y; other.y = nullptr; - if (z) BN_free (z); z = other.z; other.z = nullptr; - if (t) BN_free (t); t = other.t; other.t = nullptr; + if (this != &other) + { + BN_free (x); x = other.x; other.x = nullptr; + BN_free (y); y = other.y; other.y = nullptr; + BN_free (z); z = other.z; other.z = nullptr; + BN_free (t); t = other.t; other.t = nullptr; + } return *this; } EDDSAPoint& operator=(const EDDSAPoint& other) { - if (x) BN_free (x); x = other.x ? BN_dup (other.x) : nullptr; - if (y) BN_free (y); y = other.y ? BN_dup (other.y) : nullptr; - if (z) BN_free (z); z = other.z ? BN_dup (other.z) : nullptr; - if (t) BN_free (t); t = other.t ? BN_dup (other.t) : nullptr; + if (this != &other) + { + BN_free (x); x = other.x ? BN_dup (other.x) : nullptr; + BN_free (y); y = other.y ? BN_dup (other.y) : nullptr; + BN_free (z); z = other.z ? BN_dup (other.z) : nullptr; + BN_free (t); t = other.t ? BN_dup (other.t) : nullptr; + } return *this; } From 346bf14b7bbac8cfbea3ac5be089907f1fc5d033 Mon Sep 17 00:00:00 2001 From: brain5lug Date: Fri, 29 Sep 2017 10:17:23 +0300 Subject: [PATCH 59/81] added missed invariant for MemoryPool --- libi2pd/util.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libi2pd/util.h b/libi2pd/util.h index 1a9b9a73..5297b3ed 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -33,6 +33,8 @@ namespace util template class MemoryPool { + BOOST_STATIC_ASSERT_MSG(sizeof(T) >= sizeof(void*), "size cannot be less that general pointer size"); + public: MemoryPool (): m_Head (nullptr) {} From 8460a8f4efff61a27e7fa6121e61ac400d3e8b39 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 29 Sep 2017 15:34:26 -0400 Subject: [PATCH 60/81] update local destination if changed --- libi2pd_client/ClientContext.cpp | 10 ++++++++++ libi2pd_client/I2PService.h | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index 743c1388..e84bcb5f 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -567,6 +567,11 @@ namespace client else { // TODO: update + if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ()) + { + LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated"); + ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ()); + } ins.first->second->isUpdated = true; LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists"); } @@ -673,6 +678,11 @@ namespace client else { // TODO: update + if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ()) + { + LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated"); + ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ()); + } ins.first->second->isUpdated = true; LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); } diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index b708125f..60fd29ee 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -41,7 +41,12 @@ namespace client inline std::shared_ptr GetLocalDestination () { return m_LocalDestination; } inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } - inline void SetLocalDestination (std::shared_ptr dest) { m_LocalDestination = dest; } + inline void SetLocalDestination (std::shared_ptr dest) + { + if (m_LocalDestination) m_LocalDestination->Release (); + if (dest) dest->Acquire (); + m_LocalDestination = dest; + } void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0); void CreateStream(StreamRequestComplete complete, const i2p::data::IdentHash & ident, int port); inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); } From 6e32f4bc85df9b53af188c59a2f6de97b43908a9 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Oct 2017 12:27:08 -0400 Subject: [PATCH 61/81] set nickname for destination --- libi2pd/Destination.cpp | 15 ++++++++++++--- libi2pd/Destination.h | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index b0e3365a..a2ba765b 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -23,8 +23,10 @@ namespace client int outQty = DEFAULT_OUTBOUND_TUNNELS_QUANTITY; int numTags = DEFAULT_TAGS_TO_SEND; std::shared_ptr > explicitPeers; - try { - if (params) { + try + { + if (params) + { auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH); if (it != params->end ()) inLen = std::stoi(it->second); @@ -55,8 +57,15 @@ namespace client LogPrint (eLogInfo, "Destination: Added to explicit peers list: ", b64); } } + it = params->find (I2CP_PARAM_INBOUND_NICKNAME); + if (it != params->end ()) + m_Nickname = it->second; + else + m_Nickname = i2p::data::GetIdentHashAbbreviation (GetIdentHash ()); } - } catch (std::exception & ex) { + } + catch (std::exception & ex) + { LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what()); } SetNumTags (numTags); diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index ef7437fb..b4c20fcc 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -50,6 +50,7 @@ namespace client const int STREAM_REQUEST_TIMEOUT = 60; //in seconds const char I2CP_PARAM_TAGS_TO_SEND[] = "crypto.tagsToSend"; const int DEFAULT_TAGS_TO_SEND = 40; + const char I2CP_PARAM_INBOUND_NICKNAME[] = "inbound.nickname"; // latency const char I2CP_PARAM_MIN_TUNNEL_LATENCY[] = "latency.min"; @@ -86,6 +87,7 @@ namespace client LeaseSetDestination (bool isPublic, const std::map * params = nullptr); ~LeaseSetDestination (); + const std::string& GetNickname () const { return m_Nickname; }; virtual bool Start (); virtual bool Stop (); @@ -153,6 +155,7 @@ namespace client boost::asio::deadline_timer m_PublishConfirmationTimer, m_PublishVerificationTimer, m_PublishDelayTimer, m_CleanupTimer; + std::string m_Nickname; public: From 7d7f5ff4e26c29113d6287d660b23c2f97766576 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Oct 2017 12:40:43 -0400 Subject: [PATCH 62/81] set default nickname after initialization --- libi2pd/Destination.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index a2ba765b..d6d92388 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -58,10 +58,7 @@ namespace client } } it = params->find (I2CP_PARAM_INBOUND_NICKNAME); - if (it != params->end ()) - m_Nickname = it->second; - else - m_Nickname = i2p::data::GetIdentHashAbbreviation (GetIdentHash ()); + if (it != params->end ()) m_Nickname = it->second; // otherwise we set deafult nickname in Start when we know local address } } catch (std::exception & ex) @@ -119,6 +116,8 @@ namespace client { if (!m_IsRunning) { + if (m_Nickname.empty ()) + m_Nickname = i2p::data::GetIdentHashAbbreviation (GetIdentHash ()); // set default nickname LoadTags (); m_IsRunning = true; m_Pool->SetLocalDestination (shared_from_this ()); From 057d6ca05bfc099f780b5d74a0d3c51a2f66bba5 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Wed, 4 Oct 2017 20:15:29 +0300 Subject: [PATCH 63/81] windows warnings, tabulation workaround --- Win32/DaemonWin32.cpp | 3 +- Win32/Win32Service.cpp | 63 ++---------- Win32/Win32Service.h | 16 +-- libi2pd_client/I2PService.cpp | 97 +++++++++--------- libi2pd_client/I2PService.h | 69 +++++++------ libi2pd_client/I2PTunnel.cpp | 184 ++++++++++++++++------------------ libi2pd_client/I2PTunnel.h | 99 +++++++----------- 7 files changed, 229 insertions(+), 302 deletions(-) diff --git a/Win32/DaemonWin32.cpp b/Win32/DaemonWin32.cpp index d36949c3..3f9226d1 100644 --- a/Win32/DaemonWin32.cpp +++ b/Win32/DaemonWin32.cpp @@ -6,7 +6,6 @@ #include "Log.h" #ifdef _WIN32 - #include "Win32/Win32Service.h" #ifdef WIN32_APP #include "Win32/Win32App.h" @@ -109,4 +108,4 @@ namespace util } } } -#endif +#endif //_WIN32 diff --git a/Win32/Win32Service.cpp b/Win32/Win32Service.cpp index d3785999..4a0058ac 100644 --- a/Win32/Win32Service.cpp +++ b/Win32/Win32Service.cpp @@ -15,7 +15,6 @@ I2PService *I2PService::s_service = NULL; BOOL I2PService::isService() { BOOL bIsService = FALSE; - HWINSTA hWinStation = GetProcessWindowStation(); if (hWinStation != NULL) { @@ -31,28 +30,23 @@ BOOL I2PService::isService() BOOL I2PService::Run(I2PService &service) { s_service = &service; - SERVICE_TABLE_ENTRY serviceTable[] = { { service.m_name, ServiceMain }, { NULL, NULL } }; - return StartServiceCtrlDispatcher(serviceTable); } - void WINAPI I2PService::ServiceMain(DWORD dwArgc, PSTR *pszArgv) { assert(s_service != NULL); - s_service->m_statusHandle = RegisterServiceCtrlHandler( s_service->m_name, ServiceCtrlHandler); if (s_service->m_statusHandle == NULL) { throw GetLastError(); } - s_service->Start(dwArgc, pszArgv); } @@ -61,12 +55,12 @@ void WINAPI I2PService::ServiceCtrlHandler(DWORD dwCtrl) { switch (dwCtrl) { - case SERVICE_CONTROL_STOP: s_service->Stop(); break; - case SERVICE_CONTROL_PAUSE: s_service->Pause(); break; - case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break; - case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break; - case SERVICE_CONTROL_INTERROGATE: break; - default: break; + case SERVICE_CONTROL_STOP: s_service->Stop(); break; + case SERVICE_CONTROL_PAUSE: s_service->Pause(); break; + case SERVICE_CONTROL_CONTINUE: s_service->Continue(); break; + case SERVICE_CONTROL_SHUTDOWN: s_service->Shutdown(); break; + case SERVICE_CONTROL_INTERROGATE: break; + default: break; } } @@ -76,11 +70,8 @@ I2PService::I2PService(PSTR pszServiceName, BOOL fCanPauseContinue) { m_name = (pszServiceName == NULL) ? (PSTR)"" : pszServiceName; - m_statusHandle = NULL; - m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - m_status.dwCurrentState = SERVICE_START_PENDING; DWORD dwControlsAccepted = 0; @@ -90,15 +81,13 @@ I2PService::I2PService(PSTR pszServiceName, dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN; if (fCanPauseContinue) dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE; - m_status.dwControlsAccepted = dwControlsAccepted; + m_status.dwControlsAccepted = dwControlsAccepted; m_status.dwWin32ExitCode = NO_ERROR; m_status.dwServiceSpecificExitCode = 0; m_status.dwCheckPoint = 0; m_status.dwWaitHint = 0; - m_fStopping = FALSE; - // Create a manual-reset event that is not signaled at first to indicate // the stopped signal of the service. m_hStoppedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -108,7 +97,6 @@ I2PService::I2PService(PSTR pszServiceName, } } - I2PService::~I2PService(void) { if (m_hStoppedEvent) @@ -118,92 +106,73 @@ I2PService::~I2PService(void) } } - void I2PService::Start(DWORD dwArgc, PSTR *pszArgv) { try { SetServiceStatus(SERVICE_START_PENDING); - OnStart(dwArgc, pszArgv); - SetServiceStatus(SERVICE_RUNNING); } catch (DWORD dwError) { LogPrint(eLogError, "Win32Service Start", dwError); - SetServiceStatus(SERVICE_STOPPED, dwError); } catch (...) { LogPrint(eLogError, "Win32Service failed to start.", EVENTLOG_ERROR_TYPE); - SetServiceStatus(SERVICE_STOPPED); } } - void I2PService::OnStart(DWORD dwArgc, PSTR *pszArgv) { LogPrint(eLogInfo, "Win32Service in OnStart", EVENTLOG_INFORMATION_TYPE); - Daemon.start(); - //i2p::util::config::OptionParser(dwArgc, pszArgv); //i2p::util::filesystem::ReadConfigFile(i2p::util::config::mapArgs, i2p::util::config::mapMultiArgs); //i2p::context.OverrideNTCPAddress(i2p::util::config::GetCharArg("-host", "127.0.0.1"), // i2p::util::config::GetArg("-port", 17070)); - _worker = new std::thread(std::bind(&I2PService::WorkerThread, this)); } - void I2PService::WorkerThread() { while (!m_fStopping) { ::Sleep(1000); // Simulate some lengthy operations. } - // Signal the stopped event. SetEvent(m_hStoppedEvent); } - void I2PService::Stop() { DWORD dwOriginalState = m_status.dwCurrentState; try { SetServiceStatus(SERVICE_STOP_PENDING); - OnStop(); - SetServiceStatus(SERVICE_STOPPED); } catch (DWORD dwError) { LogPrint(eLogInfo, "Win32Service Stop", dwError); - SetServiceStatus(dwOriginalState); } catch (...) { LogPrint(eLogError, "Win32Service failed to stop.", EVENTLOG_ERROR_TYPE); - SetServiceStatus(dwOriginalState); } } - void I2PService::OnStop() { // Log a service stop message to the Application log. LogPrint(eLogInfo, "Win32Service in OnStop", EVENTLOG_INFORMATION_TYPE); - Daemon.stop(); - m_fStopping = TRUE; if (WaitForSingleObject(m_hStoppedEvent, INFINITE) != WAIT_OBJECT_0) { @@ -213,57 +182,46 @@ void I2PService::OnStop() delete _worker; } - void I2PService::Pause() { try { SetServiceStatus(SERVICE_PAUSE_PENDING); - OnPause(); - SetServiceStatus(SERVICE_PAUSED); } catch (DWORD dwError) { LogPrint(eLogError, "Win32Service Pause", dwError); - SetServiceStatus(SERVICE_RUNNING); } catch (...) { LogPrint(eLogError, "Win32Service failed to pause.", EVENTLOG_ERROR_TYPE); - SetServiceStatus(SERVICE_RUNNING); } } - void I2PService::OnPause() { } - void I2PService::Continue() { try { SetServiceStatus(SERVICE_CONTINUE_PENDING); - OnContinue(); - SetServiceStatus(SERVICE_RUNNING); } catch (DWORD dwError) { LogPrint(eLogError, "Win32Service Continue", dwError); - SetServiceStatus(SERVICE_PAUSED); } catch (...) { LogPrint(eLogError, "Win32Service failed to resume.", EVENTLOG_ERROR_TYPE); - SetServiceStatus(SERVICE_PAUSED); } } @@ -277,7 +235,6 @@ void I2PService::Shutdown() try { OnShutdown(); - SetServiceStatus(SERVICE_STOPPED); } catch (DWORD dwError) @@ -299,11 +256,9 @@ void I2PService::SetServiceStatus(DWORD dwCurrentState, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; - m_status.dwCurrentState = dwCurrentState; m_status.dwWin32ExitCode = dwWin32ExitCode; m_status.dwWaitHint = dwWaitHint; - m_status.dwCheckPoint = ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) ? @@ -328,7 +283,7 @@ void FreeHandles(SC_HANDLE schSCManager, SC_HANDLE schService) } } -void InstallService(PSTR pszServiceName, PSTR pszDisplayName, DWORD dwStartType, PSTR pszDependencies, PSTR pszAccount, PSTR pszPassword) +void InstallService(PCSTR pszServiceName, PCSTR pszDisplayName, DWORD dwStartType, PCSTR pszDependencies, PCSTR pszAccount, PCSTR pszPassword) { printf("Try to install Win32Service (%s).\n", pszServiceName); @@ -383,7 +338,7 @@ void InstallService(PSTR pszServiceName, PSTR pszDisplayName, DWORD dwStartType, FreeHandles(schSCManager, schService); } -void UninstallService(PSTR pszServiceName) +void UninstallService(PCSTR pszServiceName) { printf("Try to uninstall Win32Service (%s).\n", pszServiceName); diff --git a/Win32/Win32Service.h b/Win32/Win32Service.h index 95cad3b5..2830d237 100644 --- a/Win32/Win32Service.h +++ b/Win32/Win32Service.h @@ -4,7 +4,6 @@ #include #include - #ifdef _WIN32 // Internal name of the service #define SERVICE_NAME "i2pdService" @@ -25,7 +24,6 @@ #define SERVICE_PASSWORD NULL #endif - class I2PService { public: @@ -72,13 +70,15 @@ private: std::thread* _worker; }; -void InstallService(PSTR pszServiceName, - PSTR pszDisplayName, +void InstallService( + PCSTR pszServiceName, + PCSTR pszDisplayName, DWORD dwStartType, - PSTR pszDependencies, - PSTR pszAccount, - PSTR pszPassword); + PCSTR pszDependencies, + PCSTR pszAccount, + PCSTR pszPassword + ); -void UninstallService(PSTR pszServiceName); +void UninstallService(PCSTR pszServiceName); #endif // WIN_32_SERVICE_H__ \ No newline at end of file diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index a90cf3d4..6fd5d763 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -13,8 +13,8 @@ namespace client I2PService::I2PService (std::shared_ptr localDestination): m_LocalDestination (localDestination ? localDestination : i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)), - m_ReadyTimer(m_LocalDestination->GetService()), - m_ConnectTimeout(0), + m_ReadyTimer(m_LocalDestination->GetService()), + m_ConnectTimeout(0), isUpdated (true) { m_LocalDestination->Acquire (); @@ -49,7 +49,7 @@ namespace client { if(timeout && !m_ConnectTimeout) { - TriggerReadyCheckTimer(); + TriggerReadyCheckTimer(); } else if (m_ConnectTimeout && !timeout) { @@ -104,9 +104,7 @@ namespace client assert(streamRequestComplete); i2p::data::IdentHash identHash; if (i2p::client::context.GetAddressBook ().GetIdentHash (dest, identHash)) - { CreateStream(streamRequestComplete, identHash, port); - } else { LogPrint (eLogWarning, "I2PService: Remote destination not found: ", dest); @@ -158,16 +156,16 @@ namespace client void TCPIPPipe::Terminate() { if(Kill()) return; - if (m_up) { - if (m_up->is_open()) { + if (m_up) + { + if (m_up->is_open()) m_up->close(); - } m_up = nullptr; } - if (m_down) { - if (m_down->is_open()) { + if (m_down) + { + if (m_down->is_open()) m_down->close(); - } m_down = nullptr; } Done(shared_from_this()); @@ -175,103 +173,106 @@ namespace client void TCPIPPipe::AsyncReceiveUpstream() { - if (m_up) { + if (m_up) + { m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE), - std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); - } else { - LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket"); + std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } + else + LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket"); } void TCPIPPipe::AsyncReceiveDownstream() { if (m_down) { m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE), - std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); - } else { - LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket"); + std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } + else + LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket"); } void TCPIPPipe::UpstreamWrite(size_t len) { - if (m_up) { + if (m_up) + { LogPrint(eLogDebug, "TCPIPPipe: upstream: ", (int) len, " bytes written"); boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len), - boost::asio::transfer_all(), - std::bind(&TCPIPPipe::HandleUpstreamWrite, - shared_from_this(), - std::placeholders::_1) - ); - } else { - LogPrint(eLogError, "TCPIPPipe: upstream write: no socket"); + boost::asio::transfer_all(), + std::bind(&TCPIPPipe::HandleUpstreamWrite, + shared_from_this(), + std::placeholders::_1)); } + else + LogPrint(eLogError, "TCPIPPipe: upstream write: no socket"); } void TCPIPPipe::DownstreamWrite(size_t len) { - if (m_down) { + if (m_down) + { LogPrint(eLogDebug, "TCPIPPipe: downstream: ", (int) len, " bytes written"); boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len), - boost::asio::transfer_all(), - std::bind(&TCPIPPipe::HandleDownstreamWrite, - shared_from_this(), - std::placeholders::_1) - ); - } else { - LogPrint(eLogError, "TCPIPPipe: downstream write: no socket"); + boost::asio::transfer_all(), + std::bind(&TCPIPPipe::HandleDownstreamWrite, + shared_from_this(), + std::placeholders::_1)); } + else + LogPrint(eLogError, "TCPIPPipe: downstream write: no socket"); } void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { LogPrint(eLogDebug, "TCPIPPipe: downstream: ", (int) bytes_transfered, " bytes received"); - if (ecode) { + if (ecode) + { LogPrint(eLogError, "TCPIPPipe: downstream read error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); } else { - if (bytes_transfered > 0 ) { + if (bytes_transfered > 0 ) memcpy(m_upstream_buf, m_downstream_to_up_buf, bytes_transfered); - } UpstreamWrite(bytes_transfered); } } void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) { - if (ecode) { + if (ecode) + { LogPrint(eLogError, "TCPIPPipe: downstream write error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); - } else { - AsyncReceiveUpstream(); } + else + AsyncReceiveUpstream(); } void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) { - if (ecode) { + if (ecode) + { LogPrint(eLogError, "TCPIPPipe: upstream write error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); - } else { - AsyncReceiveDownstream(); } + else + AsyncReceiveDownstream(); } void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { LogPrint(eLogDebug, "TCPIPPipe: upstream ", (int)bytes_transfered, " bytes received"); - if (ecode) { + if (ecode) + { LogPrint(eLogError, "TCPIPPipe: upstream read error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); } else { - if (bytes_transfered > 0 ) { + if (bytes_transfered > 0 ) memcpy(m_downstream_buf, m_upstream_to_down_buf, bytes_transfered); - } DownstreamWrite(bytes_transfered); } } diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index 60fd29ee..fd5e8999 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -16,8 +16,9 @@ namespace client class I2PServiceHandler; class I2PService : std::enable_shared_from_this { - public: - typedef std::function ReadyCallback; + public: + typedef std::function ReadyCallback; + public: I2PService (std::shared_ptr localDestination = nullptr); I2PService (i2p::data::SigningKeyType kt); @@ -35,9 +36,9 @@ namespace client } void ClearHandlers (); - void SetConnectTimeout(uint32_t timeout); + void SetConnectTimeout(uint32_t timeout); - void AddReadyCallback(ReadyCallback cb); + void AddReadyCallback(ReadyCallback cb); inline std::shared_ptr GetLocalDestination () { return m_LocalDestination; } inline std::shared_ptr GetLocalDestination () const { return m_LocalDestination; } @@ -48,7 +49,7 @@ namespace client m_LocalDestination = dest; } void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0); - void CreateStream(StreamRequestComplete complete, const i2p::data::IdentHash & ident, int port); + void CreateStream(StreamRequestComplete complete, const i2p::data::IdentHash & ident, int port); inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); } virtual void Start () = 0; @@ -56,18 +57,17 @@ namespace client virtual const char* GetName() { return "Generic I2P Service"; } - private: - void TriggerReadyCheckTimer(); - void HandleReadyCheckTimer(const boost::system::error_code & ec); + private: + void TriggerReadyCheckTimer(); + void HandleReadyCheckTimer(const boost::system::error_code & ec); private: - std::shared_ptr m_LocalDestination; std::unordered_set > m_Handlers; std::mutex m_HandlersMutex; - std::vector > m_ReadyCallbacks; - boost::asio::deadline_timer m_ReadyTimer; - uint32_t m_ConnectTimeout; + std::vector > m_ReadyCallbacks; + boost::asio::deadline_timer m_ReadyTimer; + uint32_t m_ConnectTimeout; public: bool isUpdated; // transient, used during reload only @@ -93,6 +93,7 @@ namespace client inline void Done (std::shared_ptr me) { if(m_Service) m_Service->RemoveHandler(me); } // Call to talk with the owner inline I2PService * GetOwner() { return m_Service; } + private: I2PService *m_Service; std::atomic m_Dead; //To avoid cleaning up multiple times @@ -101,25 +102,28 @@ namespace client const size_t TCP_IP_PIPE_BUFFER_SIZE = 8192 * 8; // bidirectional pipe for 2 tcp/ip sockets - class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this { - public: - TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); - ~TCPIPPipe(); - void Start(); - protected: - void Terminate(); - void AsyncReceiveUpstream(); - void AsyncReceiveDownstream(); - void HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred); - void HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred); - void HandleUpstreamWrite(const boost::system::error_code & ecode); - void HandleDownstreamWrite(const boost::system::error_code & ecode); - void UpstreamWrite(size_t len); - void DownstreamWrite(size_t len); - private: - uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE]; - uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE]; - std::shared_ptr m_up, m_down; + class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this + { + public: + TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream); + ~TCPIPPipe(); + void Start(); + + protected: + void Terminate(); + void AsyncReceiveUpstream(); + void AsyncReceiveDownstream(); + void HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred); + void HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred); + void HandleUpstreamWrite(const boost::system::error_code & ecode); + void HandleDownstreamWrite(const boost::system::error_code & ecode); + void UpstreamWrite(size_t len); + void DownstreamWrite(size_t len); + + private: + uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE]; + uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE]; + std::shared_ptr m_up, m_down; }; /* TODO: support IPv6 too */ @@ -143,10 +147,11 @@ namespace client const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; }; - virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } + virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } protected: virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; + private: void Accept(); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 8d559aee..da5dbfee 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -29,14 +29,14 @@ namespace client } I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, - std::shared_ptr socket, std::shared_ptr stream): + std::shared_ptr socket, std::shared_ptr stream): I2PServiceHandler(owner), m_Socket (socket), m_Stream (stream), m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true) { } I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr stream, - std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, bool quiet): + std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, bool quiet): I2PServiceHandler(owner), m_Socket (socket), m_Stream (stream), m_RemoteEndpoint (target), m_IsQuiet (quiet) { @@ -137,7 +137,7 @@ namespace client auto s = shared_from_this (); m_Stream->AsyncSend (m_Buffer, bytes_transferred, [s](const boost::system::error_code& ecode) - { + { if (!ecode) s->Receive (); else @@ -164,7 +164,7 @@ namespace client if (m_Stream) { if (m_Stream->GetStatus () == i2p::stream::eStreamStatusNew || - m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular + m_Stream->GetStatus () == i2p::stream::eStreamStatusOpen) // regular { m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE), std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (), @@ -207,7 +207,7 @@ namespace client void I2PTunnelConnection::Write (const uint8_t * buf, size_t len) { boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, len), boost::asio::transfer_all (), - std::bind (&I2PTunnelConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); + std::bind (&I2PTunnelConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); } void I2PTunnelConnection::HandleConnect (const boost::system::error_code& ecode) @@ -339,48 +339,48 @@ namespace client } I2PTunnelConnectionIRC::I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, - std::shared_ptr socket, - const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass): - I2PTunnelConnection (owner, stream, socket, target), m_From (stream->GetRemoteIdentity ()), - m_NeedsWebIrc (webircpass.length() ? true : false), m_WebircPass (webircpass) - { - } + std::shared_ptr socket, + const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass): + I2PTunnelConnection (owner, stream, socket, target), m_From (stream->GetRemoteIdentity ()), + m_NeedsWebIrc (webircpass.length() ? true : false), m_WebircPass (webircpass) + { + } - void I2PTunnelConnectionIRC::Write (const uint8_t * buf, size_t len) - { + void I2PTunnelConnectionIRC::Write (const uint8_t * buf, size_t len) + { m_OutPacket.str (""); - if (m_NeedsWebIrc) + if (m_NeedsWebIrc) { - m_NeedsWebIrc = false; - m_OutPacket << "WEBIRC " << m_WebircPass << " cgiirc " << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()) << " " << GetSocket ()->local_endpoint ().address () << std::endl; - } + m_NeedsWebIrc = false; + m_OutPacket << "WEBIRC " << m_WebircPass << " cgiirc " << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()) << " " << GetSocket ()->local_endpoint ().address () << std::endl; + } - m_InPacket.clear (); - m_InPacket.write ((const char *)buf, len); + m_InPacket.clear (); + m_InPacket.write ((const char *)buf, len); - while (!m_InPacket.eof () && !m_InPacket.fail ()) - { + while (!m_InPacket.eof () && !m_InPacket.fail ()) + { std::string line; - std::getline (m_InPacket, line); - if (line.length () == 0 && m_InPacket.eof ()) - m_InPacket.str (""); - auto pos = line.find ("USER"); - if (!pos) // start of line - { - pos = line.find (" "); - pos++; - pos = line.find (" ", pos); - pos++; - auto nextpos = line.find (" ", pos); - m_OutPacket << line.substr (0, pos); - m_OutPacket << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()); - m_OutPacket << line.substr (nextpos) << '\n'; - } + std::getline (m_InPacket, line); + if (line.length () == 0 && m_InPacket.eof ()) + m_InPacket.str (""); + auto pos = line.find ("USER"); + if (!pos) // start of line + { + pos = line.find (" "); + pos++; + pos = line.find (" ", pos); + pos++; + auto nextpos = line.find (" ", pos); + m_OutPacket << line.substr (0, pos); + m_OutPacket << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()); + m_OutPacket << line.substr (nextpos) << '\n'; + } else - m_OutPacket << line << '\n'; - } - I2PTunnelConnection::Write ((uint8_t *)m_OutPacket.str ().c_str (), m_OutPacket.str ().length ()); - } + m_OutPacket << line << '\n'; + } + I2PTunnelConnection::Write ((uint8_t *)m_OutPacket.str ().c_str (), m_OutPacket.str ().length ()); + } /* This handler tries to stablish a connection with the desired server and dies if it fails to do so */ @@ -437,7 +437,7 @@ namespace client } I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, - const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): + const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort) { @@ -481,7 +481,7 @@ namespace client } I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, int inport, bool gzip): + int port, std::shared_ptr localDestination, int inport, bool gzip): I2PService (localDestination), m_IsUniqueLocal(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) { m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip); @@ -573,8 +573,8 @@ namespace client } I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, - const std::string& host, int inport, bool gzip): + int port, std::shared_ptr localDestination, + const std::string& host, int inport, bool gzip): I2PServerTunnel (name, address, port, localDestination, inport, gzip), m_Host (host) { @@ -586,30 +586,30 @@ namespace client std::make_shared (GetService ()), GetEndpoint (), m_Host); } - I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address, - int port, std::shared_ptr localDestination, - const std::string& webircpass, int inport, bool gzip): - I2PServerTunnel (name, address, port, localDestination, inport, gzip), - m_WebircPass (webircpass) - { - } + I2PServerTunnelIRC::I2PServerTunnelIRC (const std::string& name, const std::string& address, + int port, std::shared_ptr localDestination, + const std::string& webircpass, int inport, bool gzip): + I2PServerTunnel (name, address, port, localDestination, inport, gzip), + m_WebircPass (webircpass) + { + } - std::shared_ptr I2PServerTunnelIRC::CreateI2PConnection (std::shared_ptr stream) - { - return std::make_shared (this, stream, std::make_shared (GetService ()), GetEndpoint (), this->m_WebircPass); - } + std::shared_ptr I2PServerTunnelIRC::CreateI2PConnection (std::shared_ptr stream) + { + return std::make_shared (this, stream, std::make_shared (GetService ()), GetEndpoint (), this->m_WebircPass); + } - void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) - { - std::lock_guard lock(m_SessionsMutex); - auto session = ObtainUDPSession(from, toPort, fromPort); - session->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); - session->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); - } + void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len) + { + std::lock_guard lock(m_SessionsMutex); + auto session = ObtainUDPSession(from, toPort, fromPort); + session->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); + session->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); + } - void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) { - std::lock_guard lock(m_SessionsMutex); - uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); + void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) { + std::lock_guard lock(m_SessionsMutex); + uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); auto itr = m_Sessions.begin(); while(itr != m_Sessions.end()) { if(now - (*itr)->LastActivity >= delta ) @@ -617,11 +617,11 @@ namespace client else ++itr; } - } + } void I2PUDPClientTunnel::ExpireStale(const uint64_t delta) { std::lock_guard lock(m_SessionsMutex); - uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); + uint64_t now = i2p::util::GetMillisecondsSinceEpoch(); std::vector removePorts; for (const auto & s : m_Sessions) { if (now - s.second.second >= delta) @@ -630,20 +630,20 @@ namespace client for(auto port : removePorts) { m_Sessions.erase(port); } - } + } UDPSessionPtr I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort) - { - auto ih = from.GetIdentHash(); - for (auto & s : m_Sessions ) - { - if ( s->Identity == ih) - { - /** found existing session */ - LogPrint(eLogDebug, "UDPServer: found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); - return s; - } - } + { + auto ih = from.GetIdentHash(); + for (auto & s : m_Sessions ) + { + if ( s->Identity == ih) + { + /** found existing session */ + LogPrint(eLogDebug, "UDPServer: found session ", s->IPSocket.local_endpoint(), " ", ih.ToBase32()); + return s; + } + } boost::asio::ip::address addr; /** create new udp session */ if(m_IsUniqueLocal && m_LocalAddress.is_loopback()) @@ -654,16 +654,16 @@ namespace client else addr = m_LocalAddress; boost::asio::ip::udp::endpoint ep(addr, 0); - m_Sessions.push_back(std::make_shared(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort)); + m_Sessions.push_back(std::make_shared(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort)); auto & back = m_Sessions.back(); return back; - } + } - UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint, - const std::shared_ptr & localDestination, - boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash * to, - uint16_t ourPort, uint16_t theirPort) : - m_Destination(localDestination->GetDatagramDestination()), + UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint, + const std::shared_ptr & localDestination, + boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash * to, + uint16_t ourPort, uint16_t theirPort) : + m_Destination(localDestination->GetDatagramDestination()), IPSocket(localDestination->GetService(), localEndpoint), SendEndpoint(endpoint), LastActivity(i2p::util::GetMillisecondsSinceEpoch()), @@ -674,7 +674,6 @@ namespace client Receive(); } - void UDPSession::Receive() { LogPrint(eLogDebug, "UDPSession: Receive"); IPSocket.async_receive_from(boost::asio::buffer(m_Buffer, I2P_UDP_MAX_MTU), @@ -694,8 +693,6 @@ namespace client } } - - I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) : m_IsUniqueLocal(true), @@ -759,13 +756,11 @@ namespace client { auto dgram = m_LocalDest->CreateDatagramDestination(); dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, - std::placeholders::_5)); + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, + std::placeholders::_5)); } - - void I2PUDPClientTunnel::Start() { m_LocalDest->Start(); if (m_ResolveThread == nullptr) @@ -850,7 +845,6 @@ namespace client } else LogPrint(eLogWarning, "UDP Client: unwarrented traffic from ", from.GetIdentHash().ToBase32()); - } I2PUDPClientTunnel::~I2PUDPClientTunnel() { diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index dd78d0fe..1bdf8bb5 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -29,7 +29,6 @@ namespace client class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this { public: - I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr leaseSet, int port = 0); // to I2P I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, @@ -41,7 +40,6 @@ namespace client void Connect (bool isUniqueLocal = true); protected: - void Terminate (); void Receive (); @@ -56,7 +54,6 @@ namespace client std::shared_ptr GetSocket () const { return m_Socket; }; private: - uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE]; std::shared_ptr m_Socket; std::shared_ptr m_Stream; @@ -67,18 +64,15 @@ namespace client class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection { public: - I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream): I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false), m_ConnectionSent (false), m_ProxyConnectionSent (false) {}; protected: - void Write (const uint8_t * buf, size_t len); private: - std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent; }; @@ -86,17 +80,14 @@ namespace client class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection { public: - I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, std::shared_ptr socket, const boost::asio::ip::tcp::endpoint& target, const std::string& host); protected: - void Write (const uint8_t * buf, size_t len); private: - std::string m_Host; std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent; @@ -104,35 +95,30 @@ namespace client }; class I2PTunnelConnectionIRC: public I2PTunnelConnection - { - public: + { + public: + I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, + std::shared_ptr socket, + const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass); - I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, - std::shared_ptr socket, - const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass); + protected: + void Write (const uint8_t * buf, size_t len); - protected: - - void Write (const uint8_t * buf, size_t len); - - private: - - std::shared_ptr m_From; - std::stringstream m_OutPacket, m_InPacket; + private: + std::shared_ptr m_From; + std::stringstream m_OutPacket, m_InPacket; bool m_NeedsWebIrc; - std::string m_WebircPass; - }; + std::string m_WebircPass; + }; class I2PClientTunnel: public TCPIPAcceptor { protected: - // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); public: - I2PClientTunnel (const std::string& name, const std::string& destination, const std::string& address, int port, std::shared_ptr localDestination, int destinationPort = 0); ~I2PClientTunnel () {} @@ -143,11 +129,9 @@ namespace client const char* GetName() { return m_Name.c_str (); } private: - const i2p::data::IdentHash * GetIdentHash (); private: - std::string m_Name, m_Destination; const i2p::data::IdentHash * m_DestinationIdentHash; int m_DestinationPort; @@ -208,11 +192,11 @@ namespace client /** server side udp tunnel, many i2p inbound to 1 ip outbound */ class I2PUDPServerTunnel - { + { public: I2PUDPServerTunnel(const std::string & name, std::shared_ptr localDestination, - boost::asio::ip::address localAddress, + boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port); ~I2PUDPServerTunnel(); /** expire stale udp conversations */ @@ -225,7 +209,6 @@ namespace client void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; } private: - void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); @@ -256,22 +239,22 @@ namespace client void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT); private: - typedef std::pair UDPConvo; - void RecvFromLocal(); - void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred); + typedef std::pair UDPConvo; + void RecvFromLocal(); + void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred); void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void TryResolving(); const std::string m_Name; - std::mutex m_SessionsMutex; - std::map m_Sessions; // maps i2p port -> local udp convo + std::mutex m_SessionsMutex; + std::map m_Sessions; // maps i2p port -> local udp convo const std::string m_RemoteDest; std::shared_ptr m_LocalDest; const boost::asio::ip::udp::endpoint m_LocalEndpoint; i2p::data::IdentHash * m_RemoteIdent; std::thread * m_ResolveThread; - boost::asio::ip::udp::socket m_LocalSocket; - boost::asio::ip::udp::endpoint m_RecvEndpoint; - uint8_t m_RecvBuff[I2P_UDP_MAX_MTU]; + boost::asio::ip::udp::socket m_LocalSocket; + boost::asio::ip::udp::endpoint m_RecvEndpoint; + uint8_t m_RecvBuff[I2P_UDP_MAX_MTU]; uint16_t RemotePort; bool m_cancel_resolve; }; @@ -279,7 +262,6 @@ namespace client class I2PServerTunnel: public I2PService { public: - I2PServerTunnel (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, int inport = 0, bool gzip = true); @@ -298,10 +280,9 @@ namespace client const char* GetName() { return m_Name.c_str (); } - void SetMaxConnsPerMinute(const uint32_t conns) { m_PortDestination->SetMaxConnsPerMinute(conns); } - - private: + void SetMaxConnsPerMinute(const uint32_t conns) { m_PortDestination->SetMaxConnsPerMinute(conns); } + private: void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, std::shared_ptr resolver); @@ -310,7 +291,6 @@ namespace client virtual std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: - bool m_IsUniqueLocal; std::string m_Name, m_Address; int m_Port; @@ -323,37 +303,30 @@ namespace client class I2PServerTunnelHTTP: public I2PServerTunnel { public: - I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port, std::shared_ptr localDestination, const std::string& host, - int inport = 0, bool gzip = true); + int inport = 0, bool gzip = true); private: - std::shared_ptr CreateI2PConnection (std::shared_ptr stream); private: - std::string m_Host; }; - class I2PServerTunnelIRC: public I2PServerTunnel - { - public: + class I2PServerTunnelIRC: public I2PServerTunnel + { + public: + I2PServerTunnelIRC (const std::string& name, const std::string& address, int port, + std::shared_ptr localDestination, const std::string& webircpass, + int inport = 0, bool gzip = true); - I2PServerTunnelIRC (const std::string& name, const std::string& address, int port, - std::shared_ptr localDestination, const std::string& webircpass, - int inport = 0, bool gzip = true); - - private: - - std::shared_ptr CreateI2PConnection (std::shared_ptr stream); - - private: - - std::string m_WebircPass; - }; + private: + std::shared_ptr CreateI2PConnection (std::shared_ptr stream); + private: + std::string m_WebircPass; + }; } } From bfdf006bd27b37fb970956e312882c8834ee98e7 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 5 Oct 2017 05:29:07 +0300 Subject: [PATCH 64/81] add SAM session in webconsole --- daemon/HTTPServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 99ed0441..d08b6d20 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -589,8 +589,9 @@ namespace http { s << "SAM Sessions:
\r\n
\r\n"; for (auto& it: sam->GetSessions ()) { + auto& name = it.second->localDestination->GetNickname (); s << ""; - s << it.first << "
\r\n" << std::endl; + s << name << " (" << it.first << ")
\r\n" << std::endl; } } From fa9c39732df327e6da837849b8e2ea68b70e2607 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 5 Oct 2017 10:37:28 -0400 Subject: [PATCH 65/81] change max bandwidth limit --- libi2pd/RouterContext.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 7be25b04..87052a37 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -203,8 +203,9 @@ namespace i2p } } - void RouterContext::SetBandwidth (char L) { - uint16_t limit = 0; + void RouterContext::SetBandwidth (char L) + { + uint32_t limit = 0; enum { low, high, extra, unlim } type = high; /* detect parameters */ switch (L) @@ -215,7 +216,7 @@ namespace i2p case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = 256; type = high; break; case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break; - case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 9999; type = unlim; break; + case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 1000000; type = unlim; break; // 1Gbyte/s default: limit = 48; type = low; } From 291f28fcceabe83d3ba4c49b4a5700fc9e90af48 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 8 Oct 2017 18:32:15 -0400 Subject: [PATCH 66/81] cmake: add stdlib args for clang build on Linux Otherwise linking fails with undefined symbol ... basic_string ... and libstdc++: DSO not on included in link command. --- build/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 6b0c0cf3..03e4c450 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -178,6 +178,9 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") endif () elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # more tweaks + if (NOT (MSVC OR MSYS OR APPLE)) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++" ) + endif() endif () if (WITH_HARDENING AND MSVC) @@ -457,6 +460,12 @@ if (WITH_BINARY) fixup_bundle(\"${APPS}\" \"\" \"${DIRS}\") " COMPONENT Runtime) endif () + + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (NOT (MSVC OR MSYS OR APPLE)) # for Clang build on Linux + target_link_libraries("${PROJECT_NAME}" stdc++) + endif() + endif() endif () install(FILES ../LICENSE From b347b719f3bd51a2a4f2e9181c193d748564b501 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 Oct 2017 14:38:32 -0400 Subject: [PATCH 67/81] fixed race condition --- libi2pd_client/SAM.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 7fcf8fbf..25aec108 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -692,8 +692,9 @@ namespace client } else { - boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), - std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); + if (m_SocketType != eSAMSocketTypeTerminated) // check for possible race condition with Terminate() + boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), + std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); } } From 7dfb6f4a1343333c32df4a538f63d3cbb1e00ac2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Thu, 12 Oct 2017 13:52:36 +0300 Subject: [PATCH 68/81] update makefiles --- Makefile | 8 +-- Makefile.mingw | 3 +- libi2pd/RouterContext.cpp | 136 +++++++++++++++++++------------------- 3 files changed, 73 insertions(+), 74 deletions(-) diff --git a/Makefile b/Makefile index 989f8586..a8514826 100644 --- a/Makefile +++ b/Makefile @@ -89,14 +89,14 @@ $(SHLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) $(CXX) $(LDFLAGS) $(LDLIBS) -shared -o $@ $^ $(ARLIB): $(patsubst %.cpp,obj/%.o,$(LIB_SRC)) - ar -r $@ $^ + $(AR) -r $@ $^ $(ARLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) - ar -r $@ $^ + $(AR) -r $@ $^ clean: - rm -rf obj - rm -rf docs/generated + $(RM) -r obj + $(RM) -r docs/generated $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB) diff --git a/Makefile.mingw b/Makefile.mingw index d6fedd7b..5b9332e2 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -47,8 +47,7 @@ ifeq ($(USE_AVX),1) endif ifeq ($(USE_ASLR),yes) - LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va \ - -Wl,--dynamicbase,--export-all-symbols + LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va -Wl,--dynamicbase,--export-all-symbols endif obj/%.o : %.rc diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 87052a37..ff19d27f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -16,8 +16,8 @@ namespace i2p RouterContext context; RouterContext::RouterContext (): - m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_StartupTime (0), m_ShareRatio (100), m_Status (eRouterStatusOK), + m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), + m_StartupTime (0), m_ShareRatio (100), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -33,11 +33,11 @@ namespace i2p void RouterContext::CreateNewRouter () { -#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) +#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); #else m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_DSA_SHA1); -#endif +#endif SaveKeys (); NewRouterInfo (); } @@ -75,7 +75,7 @@ namespace i2p std::string host = "::"; if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only i2p::config::GetOption("host", host); - else if (!ifname.empty()) + else if (!ifname.empty()) host = i2p::util::net::GetInterfaceAddress(ifname, true).to_string(); // v6 if(ifname6.size()) @@ -84,10 +84,10 @@ namespace i2p routerInfo.AddSSUAddress (host.c_str(), port, routerInfo.GetIdentHash ()); routerInfo.AddNTCPAddress (host.c_str(), port); } - - routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | + + routerInfo.SetCaps (i2p::data::RouterInfo::eReachable | i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC - routerInfo.SetProperty ("netId", std::to_string (m_NetID)); + routerInfo.SetProperty ("netId", std::to_string (m_NetID)); routerInfo.SetProperty ("router.version", I2P_VERSION); routerInfo.CreateBuffer (m_Keys); m_RouterInfo.SetRouterIdentity (GetIdentity ()); @@ -99,39 +99,39 @@ namespace i2p m_RouterInfo.CreateBuffer (m_Keys); m_RouterInfo.SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO)); m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch (); - } + } - void RouterContext::SetStatus (RouterStatus status) - { + void RouterContext::SetStatus (RouterStatus status) + { if (status != m_Status) - { + { m_Status = status; m_Error = eRouterErrorNone; switch (m_Status) - { + { case eRouterStatusOK: SetReachable (); break; case eRouterStatusFirewalled: SetUnreachable (); - break; + break; default: ; } - } + } } - + void RouterContext::UpdatePort (int port) { bool updated = false; for (auto& address : m_RouterInfo.GetAddresses ()) { if (address->port != port) - { + { address->port = port; updated = true; - } - } + } + } if (updated) UpdateRouterInfo (); } @@ -142,11 +142,11 @@ namespace i2p for (auto& address : m_RouterInfo.GetAddresses ()) { if (address->host != host && address->IsCompatible (host)) - { + { address->host = host; updated = true; - } - } + } + } auto ts = i2p::util::GetSecondsSinceEpoch (); if (updated || ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL) UpdateRouterInfo (); @@ -156,16 +156,16 @@ namespace i2p { bool ret = m_RouterInfo.AddIntroducer (introducer); if (ret) - UpdateRouterInfo (); + UpdateRouterInfo (); return ret; - } + } void RouterContext::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e) { if (m_RouterInfo.RemoveIntroducer (e)) UpdateRouterInfo (); - } - + } + void RouterContext::SetFloodfill (bool floodfill) { m_IsFloodfill = floodfill; @@ -195,20 +195,20 @@ namespace i2p { m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family); m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG, signature); - } + } else { m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY); m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG); - } - } + } + } void RouterContext::SetBandwidth (char L) { uint32_t limit = 0; enum { low, high, extra, unlim } type = high; /* detect parameters */ - switch (L) + switch (L) { case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = 48; type = low; break; @@ -224,7 +224,7 @@ namespace i2p auto caps = m_RouterInfo.GetCaps (); caps &= ~i2p::data::RouterInfo::eHighBandwidth; caps &= ~i2p::data::RouterInfo::eExtraBandwidth; - switch (type) + switch (type) { case low : /* not set */; break; case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P' @@ -236,7 +236,7 @@ namespace i2p m_BandwidthLimit = limit; } - void RouterContext::SetBandwidth (int limit) + void RouterContext::SetBandwidth (int limit) { if (limit > 2000) { SetBandwidth('X'); } else if (limit > 256) { SetBandwidth('P'); } @@ -257,8 +257,8 @@ namespace i2p bool RouterContext::IsUnreachable () const { return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; - } - + } + void RouterContext::SetUnreachable () { // set caps @@ -267,7 +267,7 @@ namespace i2p caps |= i2p::data::RouterInfo::eUnreachable; caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer - m_RouterInfo.SetCaps (caps); + m_RouterInfo.SetCaps (caps); // remove NTCP address auto& addresses = m_RouterInfo.GetAddresses (); for (auto it = addresses.begin (); it != addresses.end (); ++it) @@ -278,12 +278,12 @@ namespace i2p addresses.erase (it); break; } - } + } // delete previous introducers - for (auto& addr : addresses) + for (auto& addr : addresses) if (addr->ssu) addr->ssu->introducers.clear (); - + // update UpdateRouterInfo (); } @@ -298,7 +298,7 @@ namespace i2p if (m_IsFloodfill) caps |= i2p::data::RouterInfo::eFloodfill; m_RouterInfo.SetCaps (caps); - + // insert NTCP back auto& addresses = m_RouterInfo.GetAddresses (); for (const auto& addr : addresses) @@ -310,16 +310,16 @@ namespace i2p m_RouterInfo.AddNTCPAddress (addr->host.to_string ().c_str (), addr->port); break; } - } + } // delete previous introducers for (auto& addr : addresses) if (addr->ssu) addr->ssu->introducers.clear (); - + // update UpdateRouterInfo (); - } - + } + void RouterContext::SetSupportsV6 (bool supportsV6) { if (supportsV6) @@ -328,7 +328,7 @@ namespace i2p m_RouterInfo.DisableV6 (); UpdateRouterInfo (); } - + void RouterContext::SetSupportsV4 (bool supportsV4) { if (supportsV4) @@ -337,11 +337,11 @@ namespace i2p m_RouterInfo.DisableV4 (); UpdateRouterInfo (); } - + void RouterContext::UpdateNTCPV6Address (const boost::asio::ip::address& host) { - bool updated = false, found = false; + bool updated = false, found = false; int port = 0; auto& addresses = m_RouterInfo.GetAddresses (); for (auto& addr: addresses) @@ -353,24 +353,24 @@ namespace i2p addr->host = host; updated = true; } - found = true; - } + found = true; + } else - port = addr->port; - } + port = addr->port; + } if (!found) { // create new address m_RouterInfo.AddNTCPAddress (host.to_string ().c_str (), port); auto mtu = i2p::util::net::GetMTU (host); if (mtu) - { + { LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); if (mtu > 1472) { // TODO: magic constant mtu = 1472; LogPrint(eLogWarning, "Router: MTU dropped to upper limit of 1472 bytes"); } - } + } m_RouterInfo.AddSSUAddress (host.to_string ().c_str (), port, GetIdentHash (), mtu ? mtu : 1472); // TODO updated = true; } @@ -385,21 +385,21 @@ namespace i2p // update routers and leasesets m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS, std::to_string(i2p::data::netdb.GetNumLeaseSets ())); m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS, std::to_string(i2p::data::netdb.GetNumRouters ())); - UpdateRouterInfo (); + UpdateRouterInfo (); } } - + bool RouterContext::Load () { std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary); if (!fk.is_open ()) return false; fk.seekg (0, std::ios::end); size_t len = fk.tellg(); - fk.seekg (0, std::ios::beg); + fk.seekg (0, std::ios::beg); if (len == sizeof (i2p::data::Keys)) // old keys file format { - i2p::data::Keys keys; + i2p::data::Keys keys; fk.read ((char *)&keys, sizeof (keys)); m_Keys = keys; } @@ -412,7 +412,7 @@ namespace i2p } m_RouterInfo.SetRouterIdentity (GetIdentity ()); - i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); + i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); if (!routerInfo.IsUnreachable ()) // router.info looks good { m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); @@ -427,16 +427,16 @@ namespace i2p { LogPrint (eLogError, ROUTER_INFO, " is malformed. Creating new"); NewRouterInfo (); - } + } if (IsUnreachable ()) SetReachable (); // we assume reachable until we discover firewall through peer tests - + return true; } void RouterContext::SaveKeys () - { + { // save in the same format as .dat files std::ofstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ofstream::binary | std::ofstream::out); size_t len = m_Keys.GetFullLen (); @@ -448,9 +448,9 @@ namespace i2p std::shared_ptr RouterContext::GetTunnelPool () const { - return i2p::tunnel::tunnels.GetExploratoryPool (); - } - + return i2p::tunnel::tunnels.GetExploratoryPool (); + } + void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) { i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from)); @@ -460,22 +460,22 @@ namespace i2p { std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::ProcessGarlicMessage (msg); - } - + } + void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr msg) { std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); - } + } void RouterContext::CleanupDestination () { std::unique_lock l(m_GarlicMutex); i2p::garlic::GarlicDestination::CleanupExpiredTags (); } - + uint32_t RouterContext::GetUptime () const { return i2p::util::GetSecondsSinceEpoch () - m_StartupTime; - } + } } From 056f076ae8aa05e8b41724d957858a0beacb6280 Mon Sep 17 00:00:00 2001 From: Chris Barry Date: Sun, 15 Oct 2017 12:53:40 -0400 Subject: [PATCH 69/81] Add apparmor profile to debian. #974 --- debian/control | 4 ++-- debian/i2pd.install | 1 + debian/rules | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 62da41d2..808cdda9 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: i2pd Section: net Priority: optional Maintainer: R4SAS -Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev, libboost-filesystem-dev, libboost-program-options-dev, libminiupnpc-dev, libssl-dev, zlib1g-dev +Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16.1~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev, libboost-filesystem-dev, libboost-program-options-dev, libminiupnpc-dev, libssl-dev, zlib1g-dev, dh-apparmor Standards-Version: 3.9.6 Homepage: http://i2pd.website/ Vcs-Git: git://github.com/PurpleI2P/i2pd.git @@ -12,7 +12,7 @@ Package: i2pd Architecture: any Pre-Depends: adduser Depends: ${shlibs:Depends}, ${misc:Depends} -Suggests: tor, privoxy +Suggests: tor, privoxy, apparmor Description: A full-featured C++ implementation of I2P client. I2P (Invisible Internet Protocol) is a universal anonymous network layer. All communications over I2P are anonymous and end-to-end encrypted, participants diff --git a/debian/i2pd.install b/debian/i2pd.install index 7298f5c7..d81101fc 100644 --- a/debian/i2pd.install +++ b/debian/i2pd.install @@ -3,3 +3,4 @@ contrib/i2pd.conf etc/i2pd/ contrib/tunnels.conf etc/i2pd/ contrib/subscriptions.txt etc/i2pd/ contrib/certificates/ usr/share/i2pd/ +contrib/apparmor/usr.sbin.i2pd etc/apparmor.d diff --git a/debian/rules b/debian/rules index 171a5269..4654ae6c 100755 --- a/debian/rules +++ b/debian/rules @@ -12,6 +12,7 @@ PREFIX=/usr %: dh $@ --parallel + dh_apparmor --profile-name=usr.sbin.i2pd -pi2pd override_dh_strip: dh_strip --dbg-package=i2pd-dbg From bc11181d5e2a212e27770e1b253b9b9ca9862673 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 23 Oct 2017 14:25:26 -0400 Subject: [PATCH 70/81] tables for GOST R 34.11 --- libi2pd/Gost.cpp | 718 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 595 insertions(+), 123 deletions(-) diff --git a/libi2pd/Gost.cpp b/libi2pd/Gost.cpp index 351dac10..8663289a 100644 --- a/libi2pd/Gost.cpp +++ b/libi2pd/Gost.cpp @@ -179,121 +179,595 @@ namespace crypto // ГОСТ 34.11-2012 - static const uint8_t sbox_[256] = + static const uint64_t T0[256] = { - 0xFC, 0xEE, 0xDD, 0x11, 0xCF, 0x6E, 0x31, 0x16, 0xFB, 0xC4, 0xFA, 0xDA, 0x23, 0xC5, 0x04, 0x4D, - 0xE9, 0x77, 0xF0, 0xDB, 0x93, 0x2E, 0x99, 0xBA, 0x17, 0x36, 0xF1, 0xBB, 0x14, 0xCD, 0x5F, 0xC1, - 0xF9, 0x18, 0x65, 0x5A, 0xE2, 0x5C, 0xEF, 0x21, 0x81, 0x1C, 0x3C, 0x42, 0x8B, 0x01, 0x8E, 0x4F, - 0x05, 0x84, 0x02, 0xAE, 0xE3, 0x6A, 0x8F, 0xA0, 0x06, 0x0B, 0xED, 0x98, 0x7F, 0xD4, 0xD3, 0x1F, - 0xEB, 0x34, 0x2C, 0x51, 0xEA, 0xC8, 0x48, 0xAB, 0xF2, 0x2A, 0x68, 0xA2, 0xFD, 0x3A, 0xCE, 0xCC, - 0xB5, 0x70, 0x0E, 0x56, 0x08, 0x0C, 0x76, 0x12, 0xBF, 0x72, 0x13, 0x47, 0x9C, 0xB7, 0x5D, 0x87, - 0x15, 0xA1, 0x96, 0x29, 0x10, 0x7B, 0x9A, 0xC7, 0xF3, 0x91, 0x78, 0x6F, 0x9D, 0x9E, 0xB2, 0xB1, - 0x32, 0x75, 0x19, 0x3D, 0xFF, 0x35, 0x8A, 0x7E, 0x6D, 0x54, 0xC6, 0x80, 0xC3, 0xBD, 0x0D, 0x57, - 0xDF, 0xF5, 0x24, 0xA9, 0x3E, 0xA8, 0x43, 0xC9, 0xD7, 0x79, 0xD6, 0xF6, 0x7C, 0x22, 0xB9, 0x03, - 0xE0, 0x0F, 0xEC, 0xDE, 0x7A, 0x94, 0xB0, 0xBC, 0xDC, 0xE8, 0x28, 0x50, 0x4E, 0x33, 0x0A, 0x4A, - 0xA7, 0x97, 0x60, 0x73, 0x1E, 0x00, 0x62, 0x44, 0x1A, 0xB8, 0x38, 0x82, 0x64, 0x9F, 0x26, 0x41, - 0xAD, 0x45, 0x46, 0x92, 0x27, 0x5E, 0x55, 0x2F, 0x8C, 0xA3, 0xA5, 0x7D, 0x69, 0xD5, 0x95, 0x3B, - 0x07, 0x58, 0xB3, 0x40, 0x86, 0xAC, 0x1D, 0xF7, 0x30, 0x37, 0x6B, 0xE4, 0x88, 0xD9, 0xE7, 0x89, - 0xE1, 0x1B, 0x83, 0x49, 0x4C, 0x3F, 0xF8, 0xFE, 0x8D, 0x53, 0xAA, 0x90, 0xCA, 0xD8, 0x85, 0x61, - 0x20, 0x71, 0x67, 0xA4, 0x2D, 0x2B, 0x09, 0x5B, 0xCB, 0x9B, 0x25, 0xD0, 0xBE, 0xE5, 0x6C, 0x52, - 0x59, 0xA6, 0x74, 0xD2, 0xE6, 0xF4, 0xB4, 0xC0, 0xD1, 0x66, 0xAF, 0xC2, 0x39, 0x4B, 0x63, 0xB6 + 0xE6F87E5C5B711FD0, 0x258377800924FA16, 0xC849E07E852EA4A8, 0x5B4686A18F06C16A, + 0x0B32E9A2D77B416E, 0xABDA37A467815C66, 0xF61796A81A686676, 0xF5DC0B706391954B, + 0x4862F38DB7E64BF1, 0xFF5C629A68BD85C5, 0xCB827DA6FCD75795, 0x66D36DAF69B9F089, + 0x356C9F74483D83B0, 0x7CBCECB1238C99A1, 0x36A702AC31C4708D, 0x9EB6A8D02FBCDFD6, + 0x8B19FA51E5B3AE37, 0x9CCFB5408A127D0B, 0xBC0C78B508208F5A, 0xE533E3842288ECED, + 0xCEC2C7D377C15FD2, 0xEC7817B6505D0F5E, 0xB94CC2C08336871D, 0x8C205DB4CB0B04AD, + 0x763C855B28A0892F, 0x588D1B79F6FF3257, 0x3FECF69E4311933E, 0x0FC0D39F803A18C9, + 0xEE010A26F5F3AD83, 0x10EFE8F4411979A6, 0x5DCDA10C7DE93A10, 0x4A1BEE1D1248E92C, + 0x53BFF2DB21847339, 0xB4F50CCFA6A23D09, 0x5FB4BC9CD84798CD, 0xE88A2D8B071C56F9, + 0x7F7771695A756A9C, 0xC5F02E71A0BA1EBC, 0xA663F9AB4215E672, 0x2EB19E22DE5FBB78, + 0x0DB9CE0F2594BA14, 0x82520E6397664D84, 0x2F031E6A0208EA98, 0x5C7F2144A1BE6BF0, + 0x7A37CB1CD16362DB, 0x83E08E2B4B311C64, 0xCF70479BAB960E32, 0x856BA986B9DEE71E, + 0xB5478C877AF56CE9, 0xB8FE42885F61D6FD, 0x1BDD0156966238C8, 0x622157923EF8A92E, + 0xFC97FF42114476F8, 0x9D7D350856452CEB, 0x4C90C9B0E0A71256, 0x2308502DFBCB016C, + 0x2D7A03FAA7A64845, 0xF46E8B38BFC6C4AB, 0xBDBEF8FDD477DEBA, 0x3AAC4CEBC8079B79, + 0xF09CB105E8879D0C, 0x27FA6A10AC8A58CB, 0x8960E7C1401D0CEA, 0x1A6F811E4A356928, + 0x90C4FB0773D196FF, 0x43501A2F609D0A9F, 0xF7A516E0C63F3796, 0x1CE4A6B3B8DA9252, + 0x1324752C38E08A9B, 0xA5A864733BEC154F, 0x2BF124575549B33F, 0xD766DB15440DC5C7, + 0xA7D179E39E42B792, 0xDADF151A61997FD3, 0x86A0345EC0271423, 0x38D5517B6DA939A4, + 0x6518F077104003B4, 0x02791D90A5AEA2DD, 0x88D267899C4A5D0A, 0x930F66DF0A2865C2, + 0x4EE9D4204509B08B, 0x325538916685292A, 0x412907BFC533A842, 0xB27E2B62544DC673, + 0x6C5304456295E007, 0x5AF406E95351908A, 0x1F2F3B6BC123616F, 0xC37B09DC5255E5C6, + 0x3967D133B1FE6844, 0x298839C7F0E711E2, 0x409B87F71964F9A2, 0xE938ADC3DB4B0719, + 0x0C0B4E47F9C3EBF4, 0x5534D576D36B8843, 0x4610A05AEB8B02D8, 0x20C3CDF58232F251, + 0x6DE1840DBEC2B1E7, 0xA0E8DE06B0FA1D08, 0x7B854B540D34333B, 0x42E29A67BCCA5B7F, + 0xD8A6088AC437DD0E, 0xC63BB3A9D943ED81, 0x21714DBD5E65A3B1, 0x6761EDE7B5EEA169, + 0x2431F7C8D573ABF6, 0xD51FC685E1A3671A, 0x5E063CD40410C92D, 0x283AB98F2CB04002, + 0x8FEBC06CB2F2F790, 0x17D64F116FA1D33C, 0xE07359F1A99EE4AA, 0x784ED68C74CDC006, + 0x6E2A19D5C73B42DA, 0x8712B4161C7045C3, 0x371582E4ED93216D, 0xACE390414939F6FC, + 0x7EC5F12186223B7C, 0xC0B094042BAC16FB, 0xF9D745379A527EBF, 0x737C3F2EA3B68168, + 0x33E7B8D9BAD278CA, 0xA9A32A34C22FFEBB, 0xE48163CCFEDFBD0D, 0x8E5940246EA5A670, + 0x51C6EF4B842AD1E4, 0x22BAD065279C508C, 0xD91488C218608CEE, 0x319EA5491F7CDA17, + 0xD394E128134C9C60, 0x094BF43272D5E3B3, 0x9BF612A5A4AAD791, 0xCCBBDA43D26FFD0F, + 0x34DE1F3C946AD250, 0x4F5B5468995EE16B, 0xDF9FAF6FEA8F7794, 0x2648EA5870DD092B, + 0xBFC7E56D71D97C67, 0xDDE6B2FF4F21D549, 0x3C276B463AE86003, 0x91767B4FAF86C71F, + 0x68A13E7835D4B9A0, 0xB68C115F030C9FD4, 0x141DD2C916582001, 0x983D8F7DDD5324AC, + 0x64AA703FCC175254, 0xC2C989948E02B426, 0x3E5E76D69F46C2DE, 0x50746F03587D8004, + 0x45DB3D829272F1E5, 0x60584A029B560BF3, 0xFBAE58A73FFCDC62, 0xA15A5E4E6CAD4CE8, + 0x4BA96E55CE1FB8CC, 0x08F9747AAE82B253, 0xC102144CF7FB471B, 0x9F042898F3EB8E36, + 0x068B27ADF2EFFB7A, 0xEDCA97FE8C0A5EBE, 0x778E0513F4F7D8CF, 0x302C2501C32B8BF7, + 0x8D92DDFC175C554D, 0xF865C57F46052F5F, 0xEAF3301BA2B2F424, 0xAA68B7ECBBD60D86, + 0x998F0F350104754C, 0x0000000000000000, 0xF12E314D34D0CCEC, 0x710522BE061823B5, + 0xAF280D9930C005C1, 0x97FD5CE25D693C65, 0x19A41CC633CC9A15, 0x95844172F8C79EB8, + 0xDC5432B7937684A9, 0x9436C13A2490CF58, 0x802B13F332C8EF59, 0xC442AE397CED4F5C, + 0xFA1CD8EFE3AB8D82, 0xF2E5AC954D293FD1, 0x6AD823E8907A1B7D, 0x4D2249F83CF043B6, + 0x03CB9DD879F9F33D, 0xDE2D2F2736D82674, 0x2A43A41F891EE2DF, 0x6F98999D1B6C133A, + 0xD4AD46CD3DF436FA, 0xBB35DF50269825C0, 0x964FDCAA813E6D85, 0xEB41B0537EE5A5C4, + 0x0540BA758B160847, 0xA41AE43BE7BB44AF, 0xE3B8C429D0671797, 0x819993BBEE9FBEB9, + 0xAE9A8DD1EC975421, 0xF3572CDD917E6E31, 0x6393D7DAE2AFF8CE, 0x47A2201237DC5338, + 0xA32343DEC903EE35, 0x79FC56C4A89A91E6, 0x01B28048DC5751E0, 0x1296F564E4B7DB7B, + 0x75F7188351597A12, 0xDB6D9552BDCE2E33, 0x1E9DBB231D74308F, 0x520D7293FDD322D9, + 0xE20A44610C304677, 0xFEEEE2D2B4EAD425, 0xCA30FDEE20800675, 0x61EACA4A47015A13, + 0xE74AFE1487264E30, 0x2CC883B27BF119A5, 0x1664CF59B3F682DC, 0xA811AA7C1E78AF5B, + 0x1D5626FB648DC3B2, 0xB73E9117DF5BCE34, 0xD05F7CF06AB56F5D, 0xFD257F0ACD132718, + 0x574DC8E676C52A9E, 0x0739A7E52EB8AA9A, 0x5486553E0F3CD9A3, 0x56FF48AEAA927B7E, + 0xBE756525AD8E2D87, 0x7D0E6CF9FFDBC841, 0x3B1ECCA31450CA99, 0x6913BE30E983E840, + 0xAD511009956EA71C, 0xB1B5B6BA2DB4354E, 0x4469BDCA4E25A005, 0x15AF5281CA0F71E1, + 0x744598CB8D0E2BF2, 0x593F9B312AA863B7, 0xEFB38A6E29A4FC63, 0x6B6AA3A04C2D4A9D, + 0x3D95EB0EE6BF31E3, 0xA291C3961554BFD5, 0x18169C8EEF9BCBF5, 0x115D68BC9D4E2846, + 0xBA875F18FACF7420, 0xD1EDFCB8B6E23EBD, 0xB00736F2F1E364AE, 0x84D929CE6589B6FE, + 0x70B7A2F6DA4F7255, 0x0E7253D75C6D4929, 0x04F23A3D574159A7, 0x0A8069EA0B2C108E, + 0x49D073C56BB11A11, 0x8AAB7A1939E4FFD7, 0xCD095A0B0E38ACEF, 0xC9FB60365979F548, + 0x92BDE697D67F3422, 0xC78933E10514BC61, 0xE1C1D9B975C9B54A, 0xD2266160CF1BCD80, + 0x9A4492ED78FD8671, 0xB3CCAB2A881A9793, 0x72CEBF667FE1D088, 0xD6D45B5D985A9427 + }; + static const uint64_t T1[256] = + { + 0xC811A8058C3F55DE, 0x65F5B43196B50619, 0xF74F96B1D6706E43, 0x859D1E8BCB43D336, + 0x5AAB8A85CCFA3D84, 0xF9C7BF99C295FCFD, 0xA21FD5A1DE4B630F, 0xCDB3EF763B8B456D, + 0x803F59F87CF7C385, 0xB27C73BE5F31913C, 0x98E3AC6633B04821, 0xBF61674C26B8F818, + 0x0FFBC995C4C130C8, 0xAAA0862010761A98, 0x6057F342210116AA, 0xF63C760C0654CC35, + 0x2DDB45CC667D9042, 0xBCF45A964BD40382, 0x68E8A0C3EF3C6F3D, 0xA7BD92D269FF73BC, + 0x290AE20201ED2287, 0xB7DE34CDE885818F, 0xD901EEA7DD61059B, 0xD6FA273219A03553, + 0xD56F1AE874CCCEC9, 0xEA31245C2E83F554, 0x7034555DA07BE499, 0xCE26D2AC56E7BEF7, + 0xFD161857A5054E38, 0x6A0E7DA4527436D1, 0x5BD86A381CDE9FF2, 0xCAF7756231770C32, + 0xB09AAED9E279C8D0, 0x5DEF1091C60674DB, 0x111046A2515E5045, 0x23536CE4729802FC, + 0xC50CBCF7F5B63CFA, 0x73A16887CD171F03, 0x7D2941AFD9F28DBD, 0x3F5E3EB45A4F3B9D, + 0x84EEFE361B677140, 0x3DB8E3D3E7076271, 0x1A3A28F9F20FD248, 0x7EBC7C75B49E7627, + 0x74E5F293C7EB565C, 0x18DCF59E4F478BA4, 0x0C6EF44FA9ADCB52, 0xC699812D98DAC760, + 0x788B06DC6E469D0E, 0xFC65F8EA7521EC4E, 0x30A5F7219E8E0B55, 0x2BEC3F65BCA57B6B, + 0xDDD04969BAF1B75E, 0x99904CDBE394EA57, 0x14B201D1E6EA40F6, 0xBBB0C08241284ADD, + 0x50F20463BF8F1DFF, 0xE8D7F93B93CBACB8, 0x4D8CB68E477C86E8, 0xC1DD1B3992268E3F, + 0x7C5AA11209D62FCB, 0x2F3D98ABDB35C9AE, 0x671369562BFD5FF5, 0x15C1E16C36CEE280, + 0x1D7EB2EDF8F39B17, 0xDA94D37DB00DFE01, 0x877BC3EC760B8ADA, 0xCB8495DFE153AE44, + 0x05A24773B7B410B3, 0x12857B783C32ABDF, 0x8EB770D06812513B, 0x536739B9D2E3E665, + 0x584D57E271B26468, 0xD789C78FC9849725, 0xA935BBFA7D1AE102, 0x8B1537A3DFA64188, + 0xD0CD5D9BC378DE7A, 0x4AC82C9A4D80CFB7, 0x42777F1B83BDB620, 0x72D2883A1D33BD75, + 0x5E7A2D4BAB6A8F41, 0xF4DAAB6BBB1C95D9, 0x905CFFE7FD8D31B6, 0x83AA6422119B381F, + 0xC0AEFB8442022C49, 0xA0F908C663033AE3, 0xA428AF0804938826, 0xADE41C341A8A53C7, + 0xAE7121EE77E6A85D, 0xC47F5C4A25929E8C, 0xB538E9AA55CDD863, 0x06377AA9DAD8EB29, + 0xA18AE87BB3279895, 0x6EDFDA6A35E48414, 0x6B7D9D19825094A7, 0xD41CFA55A4E86CBF, + 0xE5CAEDC9EA42C59C, 0xA36C351C0E6FC179, 0x5181E4DE6FABBF89, 0xFFF0C530184D17D4, + 0x9D41EB1584045892, 0x1C0D525028D73961, 0xF178EC180CA8856A, 0x9A0571018EF811CD, + 0x4091A27C3EF5EFCC, 0x19AF15239F6329D2, 0x347450EFF91EB990, 0xE11B4A078DD27759, + 0xB9561DE5FC601331, 0x912F1F5A2DA993C0, 0x1654DCB65BA2191A, 0x3E2DDE098A6B99EB, + 0x8A66D71E0F82E3FE, 0x8C51ADB7D55A08D7, 0x4533E50F8941FF7F, 0x02E6DD67BD4859EC, + 0xE068AABA5DF6D52F, 0xC24826E3FF4A75A5, 0x6C39070D88ACDDF8, 0x6486548C4691A46F, + 0xD1BEBD26135C7C0C, 0xB30F93038F15334A, 0x82D9849FC1BF9A69, 0x9C320BA85420FAE4, + 0xFA528243AFF90767, 0x9ED4D6CFE968A308, 0xB825FD582C44B147, 0x9B7691BC5EDCB3BB, + 0xC7EA619048FE6516, 0x1063A61F817AF233, 0x47D538683409A693, 0x63C2CE984C6DED30, + 0x2A9FDFD86C81D91D, 0x7B1E3B06032A6694, 0x666089EBFBD9FD83, 0x0A598EE67375207B, + 0x07449A140AFC495F, 0x2CA8A571B6593234, 0x1F986F8A45BBC2FB, 0x381AA4A050B372C2, + 0x5423A3ADD81FAF3A, 0x17273C0B8B86BB6C, 0xFE83258DC869B5A2, 0x287902BFD1C980F1, + 0xF5A94BD66B3837AF, 0x88800A79B2CABA12, 0x55504310083B0D4C, 0xDF36940E07B9EEB2, + 0x04D1A7CE6790B2C5, 0x612413FFF125B4DC, 0x26F12B97C52C124F, 0x86082351A62F28AC, + 0xEF93632F9937E5E7, 0x3507B052293A1BE6, 0xE72C30AE570A9C70, 0xD3586041AE1425E0, + 0xDE4574B3D79D4CC4, 0x92BA228040C5685A, 0xF00B0CA5DC8C271C, 0xBE1287F1F69C5A6E, + 0xF39E317FB1E0DC86, 0x495D114020EC342D, 0x699B407E3F18CD4B, 0xDCA3A9D46AD51528, + 0x0D1D14F279896924, 0x0000000000000000, 0x593EB75FA196C61E, 0x2E4E78160B116BD8, + 0x6D4AE7B058887F8E, 0xE65FD013872E3E06, 0x7A6DDBBBD30EC4E2, 0xAC97FC89CAAEF1B1, + 0x09CCB33C1E19DBE1, 0x89F3EAC462EE1864, 0x7770CF49AA87ADC6, 0x56C57ECA6557F6D6, + 0x03953DDA6D6CFB9A, 0x36928D884456E07C, 0x1EEB8F37959F608D, 0x31D6179C4EAAA923, + 0x6FAC3AD7E5C02662, 0x43049FA653991456, 0xABD3669DC052B8EE, 0xAF02C153A7C20A2B, + 0x3CCB036E3723C007, 0x93C9C23D90E1CA2C, 0xC33BC65E2F6ED7D3, 0x4CFF56339758249E, + 0xB1E94E64325D6AA6, 0x37E16D359472420A, 0x79F8E661BE623F78, 0x5214D90402C74413, + 0x482EF1FDF0C8965B, 0x13F69BC5EC1609A9, 0x0E88292814E592BE, 0x4E198B542A107D72, + 0xCCC00FCBEBAFE71B, 0x1B49C844222B703E, 0x2564164DA840E9D5, 0x20C6513E1FF4F966, + 0xBAC3203F910CE8AB, 0xF2EDD1C261C47EF0, 0x814CB945ACD361F3, 0x95FEB8944A392105, + 0x5C9CF02C1622D6AD, 0x971865F3F77178E9, 0xBD87BA2B9BF0A1F4, 0x444005B259655D09, + 0xED75BE48247FBC0B, 0x7596122E17CFF42A, 0xB44B091785E97A15, 0x966B854E2755DA9F, + 0xEEE0839249134791, 0x32432A4623C652B9, 0xA8465B47AD3E4374, 0xF8B45F2412B15E8B, + 0x2417F6F078644BA3, 0xFB2162FE7FDDA511, 0x4BBBCC279DA46DC1, 0x0173E0BDD024A276, + 0x22208C59A2BCA08A, 0x8FC4906DB836F34D, 0xE4B90D743A6667EA, 0x7147B5E0705F46EF, + 0x2782CB2A1508B039, 0xEC065EF5F45B1E7D, 0x21B5B183CFD05B10, 0xDBE733C060295C77, + 0x9FA73672394C017E, 0xCF55321186C31C81, 0xD8720E1A0D45A7ED, 0x3B8F997A3DDF8958, + 0x3AFC79C7EDFB2B2E, 0xE9A4198643EF0ECE, 0x5F09CDF67B4E2D37, 0x4F6A6BE9FA34DF04, + 0xB6ADD47038A123F9, 0x8D224D0A057EAAA1, 0xC96248B85C1BF7A8, 0xE3FD9760309A2EB5, + 0x0B2A6E5BA351820D, 0xEB42C4E1FEA75722, 0x948D58299A1D8373, 0x7FCF9CC864BAD451, + 0xA55B4FB5D4B72A50, 0x08BF5381CE3D7997, 0x46A6D8D5E42D04E5, 0xD22B80FC7E308796, + 0x57B69E77B57354A0, 0x3969441D8097D0B4, 0x3330CAFBF3E2F0CF, 0xE28E77DDE0BE8CC3, + 0x62B12E259C494F46, 0xA6CE726FB9DBD1CA, 0x41E242C1EED14DBA, 0x76032FF47AA30FB0 + }; + static const uint64_t T2[256] = + { + 0x45B268A93ACDE4CC, 0xAF7F0BE884549D08, 0x048354B3C1468263, 0x925435C2C80EFED2, + 0xEE4E37F27FDFFBA7, 0x167A33920C60F14D, 0xFB123B52EA03E584, 0x4A0CAB53FDBB9007, + 0x9DEAF6380F788A19, 0xCB48EC558F0CB32A, 0xB59DC4B2D6FEF7E0, 0xDCDBCA22F4F3ECB6, + 0x11DF5813549A9C40, 0xE33FDEDF568ACED3, 0xA0C1C8124322E9C3, 0x07A56B8158FA6D0D, + 0x77279579B1E1F3DD, 0xD9B18B74422AC004, 0xB8EC2D9FFFABC294, 0xF4ACF8A82D75914F, + 0x7BBF69B1EF2B6878, 0xC4F62FAF487AC7E1, 0x76CE809CC67E5D0C, 0x6711D88F92E4C14C, + 0x627B99D9243DEDFE, 0x234AA5C3DFB68B51, 0x909B1F15262DBF6D, 0x4F66EA054B62BCB5, + 0x1AE2CF5A52AA6AE8, 0xBEA053FBD0CE0148, 0xED6808C0E66314C9, 0x43FE16CD15A82710, + 0xCD049231A06970F6, 0xE7BC8A6C97CC4CB0, 0x337CE835FCB3B9C0, 0x65DEF2587CC780F3, + 0x52214EDE4132BB50, 0x95F15E4390F493DF, 0x870839625DD2E0F1, 0x41313C1AFB8B66AF, + 0x91720AF051B211BC, 0x477D427ED4EEA573, 0x2E3B4CEEF6E3BE25, 0x82627834EB0BCC43, + 0x9C03E3DD78E724C8, 0x2877328AD9867DF9, 0x14B51945E243B0F2, 0x574B0F88F7EB97E2, + 0x88B6FA989AA4943A, 0x19C4F068CB168586, 0x50EE6409AF11FAEF, 0x7DF317D5C04EABA4, + 0x7A567C5498B4C6A9, 0xB6BBFB804F42188E, 0x3CC22BCF3BC5CD0B, 0xD04336EAAA397713, + 0xF02FAC1BEC33132C, 0x2506DBA7F0D3488D, 0xD7E65D6BF2C31A1E, 0x5EB9B2161FF820F5, + 0x842E0650C46E0F9F, 0x716BEB1D9E843001, 0xA933758CAB315ED4, 0x3FE414FDA2792265, + 0x27C9F1701EF00932, 0x73A4C1CA70A771BE, 0x94184BA6E76B3D0E, 0x40D829FF8C14C87E, + 0x0FBEC3FAC77674CB, 0x3616A9634A6A9572, 0x8F139119C25EF937, 0xF545ED4D5AEA3F9E, + 0xE802499650BA387B, 0x6437E7BD0B582E22, 0xE6559F89E053E261, 0x80AD52E305288DFC, + 0x6DC55A23E34B9935, 0xDE14E0F51AD0AD09, 0xC6390578A659865E, 0x96D7617109487CB1, + 0xE2D6CB3A21156002, 0x01E915E5779FAED1, 0xADB0213F6A77DCB7, 0x9880B76EB9A1A6AB, + 0x5D9F8D248644CF9B, 0xFD5E4536C5662658, 0xF1C6B9FE9BACBDFD, 0xEACD6341BE9979C4, + 0xEFA7221708405576, 0x510771ECD88E543E, 0xC2BA51CB671F043D, 0x0AD482AC71AF5879, + 0xFE787A045CDAC936, 0xB238AF338E049AED, 0xBD866CC94972EE26, 0x615DA6EBBD810290, + 0x3295FDD08B2C1711, 0xF834046073BF0AEA, 0xF3099329758FFC42, 0x1CAEB13E7DCFA934, + 0xBA2307481188832B, 0x24EFCE42874CE65C, 0x0E57D61FB0E9DA1A, 0xB3D1BAD6F99B343C, + 0xC0757B1C893C4582, 0x2B510DB8403A9297, 0x5C7698C1F1DB614A, 0x3E0D0118D5E68CB4, + 0xD60F488E855CB4CF, 0xAE961E0DF3CB33D9, 0x3A8E55AB14A00ED7, 0x42170328623789C1, + 0x838B6DD19C946292, 0x895FEF7DED3B3AEB, 0xCFCBB8E64E4A3149, 0x064C7E642F65C3DC, + 0x3D2B3E2A4C5A63DA, 0x5BD3F340A9210C47, 0xB474D157A1615931, 0xAC5934DA1DE87266, + 0x6EE365117AF7765B, 0xC86ED36716B05C44, 0x9BA6885C201D49C5, 0xB905387A88346C45, + 0x131072C4BAB9DDFF, 0xBF49461EA751AF99, 0xD52977BC1CE05BA1, 0xB0F785E46027DB52, + 0x546D30BA6E57788C, 0x305AD707650F56AE, 0xC987C682612FF295, 0xA5AB8944F5FBC571, + 0x7ED528E759F244CA, 0x8DDCBBCE2C7DB888, 0xAA154ABE328DB1BA, 0x1E619BE993ECE88B, + 0x09F2BD9EE813B717, 0x7401AA4B285D1CB3, 0x21858F143195CAEE, 0x48C381841398D1B8, + 0xFCB750D3B2F98889, 0x39A86A998D1CE1B9, 0x1F888E0CE473465A, 0x7899568376978716, + 0x02CF2AD7EE2341BF, 0x85C713B5B3F1A14E, 0xFF916FE12B4567E7, 0x7C1A0230B7D10575, + 0x0C98FCC85ECA9BA5, 0xA3E7F720DA9E06AD, 0x6A6031A2BBB1F438, 0x973E74947ED7D260, + 0x2CF4663918C0FF9A, 0x5F50A7F368678E24, 0x34D983B4A449D4CD, 0x68AF1B755592B587, + 0x7F3C3D022E6DEA1B, 0xABFC5F5B45121F6B, 0x0D71E92D29553574, 0xDFFDF5106D4F03D8, + 0x081BA87B9F8C19C6, 0xDB7EA1A3AC0981BB, 0xBBCA12AD66172DFA, 0x79704366010829C7, + 0x179326777BFF5F9C, 0x0000000000000000, 0xEB2476A4C906D715, 0x724DD42F0738DF6F, + 0xB752EE6538DDB65F, 0x37FFBC863DF53BA3, 0x8EFA84FCB5C157E6, 0xE9EB5C73272596AA, + 0x1B0BDABF2535C439, 0x86E12C872A4D4E20, 0x9969A28BCE3E087A, 0xFAFB2EB79D9C4B55, + 0x056A4156B6D92CB2, 0x5A3AE6A5DEBEA296, 0x22A3B026A8292580, 0x53C85B3B36AD1581, + 0xB11E900117B87583, 0xC51F3A4A3FE56930, 0xE019E1EDCF3621BD, 0xEC811D2591FCBA18, + 0x445B7D4C4D524A1D, 0xA8DA6069DCAEF005, 0x58F5CC72309DE329, 0xD4C062596B7FF570, + 0xCE22AD0339D59F98, 0x591CD99747024DF8, 0x8B90C5AA03187B54, 0xF663D27FC356D0F0, + 0xD8589E9135B56ED5, 0x35309651D3D67A1C, 0x12F96721CD26732E, 0xD28C1C3D441A36AC, + 0x492A946164077F69, 0x2D1D73DC6F5F514B, 0x6F0A70F40D68D88A, 0x60B4B30ECA1EAC41, + 0xD36509D83385987D, 0x0B3D97490630F6A8, 0x9ECCC90A96C46577, 0xA20EE2C5AD01A87C, + 0xE49AB55E0E70A3DE, 0xA4429CA182646BA0, 0xDA97B446DB962F6A, 0xCCED87D4D7F6DE27, + 0x2AB8185D37A53C46, 0x9F25DCEFE15BCBA6, 0xC19C6EF9FEA3EB53, 0xA764A3931BD884CE, + 0x2FD2590B817C10F4, 0x56A21A6D80743933, 0xE573A0BB79EF0D0F, 0x155C0CA095DC1E23, + 0x6C2C4FC694D437E4, 0x10364DF623053291, 0xDD32DFC7836C4267, 0x03263F3299BCEF6E, + 0x66F8CD6AE57B6F9D, 0x8C35AE2B5BE21659, 0x31B3C2E21290F87F, 0x93BD2027BF915003, + 0x69460E90220D1B56, 0x299E276FAE19D328, 0x63928C3C53A2432F, 0x7082FEF8E91B9ED0, + 0xBC6F792C3EED40F7, 0x4C40D537D2DE53DB, 0x75E8BFAE5FC2B262, 0x4DA9C0D2A541FD0A, + 0x4E8FFFE03CFD1264, 0x2620E495696FA7E3, 0xE1F0F408B8A98F6C, 0xD1AA230FDDA6D9C2, + 0xC7D0109DD1C6288F, 0x8A79D04F7487D585, 0x4694579BA3710BA2, 0x38417F7CFA834F68, + 0x1D47A4DB0A5007E5, 0x206C9AF1460A643F, 0xA128DDF734BD4712, 0x8144470672B7232D, + 0xF2E086CC02105293, 0x182DE58DBC892B57, 0xCAA1F9B0F8931DFB, 0x6B892447CC2E5AE9, + 0xF9DD11850420A43B, 0x4BE5BEB68A243ED6, 0x5584255F19C8D65D, 0x3B67404E633FA006, + 0xA68DB6766C472A1F, 0xF78AC79AB4C97E21, 0xC353442E1080AAEC, 0x9A4F9DB95782E714 + }; + static const uint64_t T3[256] = + { + 0x05BA7BC82C9B3220, 0x31A54665F8B65E4F, 0xB1B651F77547F4D4, 0x8BFA0D857BA46682, + 0x85A96C5AA16A98BB, 0x990FAEF908EB79C9, 0xA15E37A247F4A62D, 0x76857DCD5D27741E, + 0xF8C50B800A1820BC, 0xBE65DCB201F7A2B4, 0x666D1B986F9426E7, 0x4CC921BF53C4E648, + 0x95410A0F93D9CA42, 0x20CDCCAA647BA4EF, 0x429A4060890A1871, 0x0C4EA4F69B32B38B, + 0xCCDA362DDE354CD3, 0x96DC23BC7C5B2FA9, 0xC309BB68AA851AB3, 0xD26131A73648E013, + 0x021DC52941FC4DB2, 0xCD5ADAB7704BE48A, 0xA77965D984ED71E6, 0x32386FD61734BBA4, + 0xE82D6DD538AB7245, 0x5C2147EA6177B4B1, 0x5DA1AB70CF091CE8, 0xAC907FCE72B8BDFF, + 0x57C85DFD972278A8, 0xA4E44C6A6B6F940D, 0x3851995B4F1FDFE4, 0x62578CCAED71BC9E, + 0xD9882BB0C01D2C0A, 0x917B9D5D113C503B, 0xA2C31E11A87643C6, 0xE463C923A399C1CE, + 0xF71686C57EA876DC, 0x87B4A973E096D509, 0xAF0D567D9D3A5814, 0xB40C2A3F59DCC6F4, + 0x3602F88495D121DD, 0xD3E1DD3D9836484A, 0xF945E71AA46688E5, 0x7518547EB2A591F5, + 0x9366587450C01D89, 0x9EA81018658C065B, 0x4F54080CBC4603A3, 0x2D0384C65137BF3D, + 0xDC325078EC861E2A, 0xEA30A8FC79573FF7, 0x214D2030CA050CB6, 0x65F0322B8016C30C, + 0x69BE96DD1B247087, 0xDB95EE9981E161B8, 0xD1FC1814D9CA05F8, 0x820ED2BBCC0DE729, + 0x63D76050430F14C7, 0x3BCCB0E8A09D3A0F, 0x8E40764D573F54A2, 0x39D175C1E16177BD, + 0x12F5A37C734F1F4B, 0xAB37C12F1FDFC26D, 0x5648B167395CD0F1, 0x6C04ED1537BF42A7, + 0xED97161D14304065, 0x7D6C67DAAB72B807, 0xEC17FA87BA4EE83C, 0xDFAF79CB0304FBC1, + 0x733F060571BC463E, 0x78D61C1287E98A27, 0xD07CF48E77B4ADA1, 0xB9C262536C90DD26, + 0xE2449B5860801605, 0x8FC09AD7F941FCFB, 0xFAD8CEA94BE46D0E, 0xA343F28B0608EB9F, + 0x9B126BD04917347B, 0x9A92874AE7699C22, 0x1B017C42C4E69EE0, 0x3A4C5C720EE39256, + 0x4B6E9F5E3EA399DA, 0x6BA353F45AD83D35, 0xE7FEE0904C1B2425, 0x22D009832587E95D, + 0x842980C00F1430E2, 0xC6B3C0A0861E2893, 0x087433A419D729F2, 0x341F3DADD42D6C6F, + 0xEE0A3FAEFBB2A58E, 0x4AEE73C490DD3183, 0xAAB72DB5B1A16A34, 0xA92A04065E238FDF, + 0x7B4B35A1686B6FCC, 0x6A23BF6EF4A6956C, 0x191CB96B851AD352, 0x55D598D4D6DE351A, + 0xC9604DE5F2AE7EF3, 0x1CA6C2A3A981E172, 0xDE2F9551AD7A5398, 0x3025AAFF56C8F616, + 0x15521D9D1E2860D9, 0x506FE31CFA45073A, 0x189C55F12B647B0B, 0x0180EC9AAE7EA859, + 0x7CEC8B40050C105E, 0x2350E5198BF94104, 0xEF8AD33455CC0DD7, 0x07A7BEE16D677F92, + 0xE5E325B90DE76997, 0x5A061591A26E637A, 0xB611EF1618208B46, 0x09F4DF3EB7A981AB, + 0x1EBB078AE87DACC0, 0xB791038CB65E231F, 0x0FD38D4574B05660, 0x67EDF702C1EA8EBE, + 0xBA5F4BE0831238CD, 0xE3C477C2CEFEBE5C, 0x0DCE486C354C1BD2, 0x8C5DB36416C31910, + 0x26EA9ED1A7627324, 0x039D29B3EF82E5EB, 0x9F28FC82CBF2AE02, 0xA8AAE89CF05D2786, + 0x431AACFA2774B028, 0xCF471F9E31B7A938, 0x581BD0B8E3922EC8, 0xBC78199B400BEF06, + 0x90FB71C7BF42F862, 0x1F3BEB1046030499, 0x683E7A47B55AD8DE, 0x988F4263A695D190, + 0xD808C72A6E638453, 0x0627527BC319D7CB, 0xEBB04466D72997AE, 0xE67E0C0AE2658C7C, + 0x14D2F107B056C880, 0x7122C32C30400B8C, 0x8A7AE11FD5DACEDB, 0xA0DEDB38E98A0E74, + 0xAD109354DCC615A6, 0x0BE91A17F655CC19, 0x8DDD5FFEB8BDB149, 0xBFE53028AF890AED, + 0xD65BA6F5B4AD7A6A, 0x7956F0882997227E, 0x10E8665532B352F9, 0x0E5361DFDACEFE39, + 0xCEC7F3049FC90161, 0xFF62B561677F5F2E, 0x975CCF26D22587F0, 0x51EF0F86543BAF63, + 0x2F1E41EF10CBF28F, 0x52722635BBB94A88, 0xAE8DBAE73344F04D, 0x410769D36688FD9A, + 0xB3AB94DE34BBB966, 0x801317928DF1AA9B, 0xA564A0F0C5113C54, 0xF131D4BEBDB1A117, + 0x7F71A2F3EA8EF5B5, 0x40878549C8F655C3, 0x7EF14E6944F05DEC, 0xD44663DCF55137D8, + 0xF2ACFD0D523344FC, 0x0000000000000000, 0x5FBC6E598EF5515A, 0x16CF342EF1AA8532, + 0xB036BD6DDB395C8D, 0x13754FE6DD31B712, 0xBBDFA77A2D6C9094, 0x89E7C8AC3A582B30, + 0x3C6B0E09CDFA459D, 0xC4AE0589C7E26521, 0x49735A777F5FD468, 0xCAFD64561D2C9B18, + 0xDA1502032F9FC9E1, 0x8867243694268369, 0x3782141E3BAF8984, 0x9CB5D53124704BE9, + 0xD7DB4A6F1AD3D233, 0xA6F989432A93D9BF, 0x9D3539AB8A0EE3B0, 0x53F2CAAF15C7E2D1, + 0x6E19283C76430F15, 0x3DEBE2936384EDC4, 0x5E3C82C3208BF903, 0x33B8834CB94A13FD, + 0x6470DEB12E686B55, 0x359FD1377A53C436, 0x61CAA57902F35975, 0x043A975282E59A79, + 0xFD7F70482683129C, 0xC52EE913699CCD78, 0x28B9FF0E7DAC8D1D, 0x5455744E78A09D43, + 0xCB7D88CCB3523341, 0x44BD121B4A13CFBA, 0x4D49CD25FDBA4E11, 0x3E76CB208C06082F, + 0x3FF627BA2278A076, 0xC28957F204FBB2EA, 0x453DFE81E46D67E3, 0x94C1E6953DA7621B, + 0x2C83685CFF491764, 0xF32C1197FC4DECA5, 0x2B24D6BD922E68F6, 0xB22B78449AC5113F, + 0x48F3B6EDD1217C31, 0x2E9EAD75BEB55AD6, 0x174FD8B45FD42D6B, 0x4ED4E4961238ABFA, + 0x92E6B4EEFEBEB5D0, 0x46A0D7320BEF8208, 0x47203BA8A5912A51, 0x24F75BF8E69E3E96, + 0xF0B1382413CF094E, 0xFEE259FBC901F777, 0x276A724B091CDB7D, 0xBDF8F501EE75475F, + 0x599B3C224DEC8691, 0x6D84018F99C1EAFE, 0x7498B8E41CDB39AC, 0xE0595E71217C5BB7, + 0x2AA43A273C50C0AF, 0xF50B43EC3F543B6E, 0x838E3E2162734F70, 0xC09492DB4507FF58, + 0x72BFEA9FDFC2EE67, 0x11688ACF9CCDFAA0, 0x1A8190D86A9836B9, 0x7ACBD93BC615C795, + 0xC7332C3A286080CA, 0x863445E94EE87D50, 0xF6966A5FD0D6DE85, 0xE9AD814F96D5DA1C, + 0x70A22FB69E3EA3D5, 0x0A69F68D582B6440, 0xB8428EC9C2EE757F, 0x604A49E3AC8DF12C, + 0x5B86F90B0C10CB23, 0xE1D9B2EB8F02F3EE, 0x29391394D3D22544, 0xC8E0A17F5CD0D6AA, + 0xB58CC6A5F7A26EAD, 0x8193FB08238F02C2, 0xD5C68F465B2F9F81, 0xFCFF9CD288FDBAC5, + 0x77059157F359DC47, 0x1D262E3907FF492B, 0xFB582233E59AC557, 0xDDB2BCE242F8B673, + 0x2577B76248E096CF, 0x6F99C4A6D83DA74C, 0xC1147E41EB795701, 0xF48BAF76912A9337 + }; + static const uint64_t T4[256] = + { + 0x3EF29D249B2C0A19, 0xE9E16322B6F8622F, 0x5536994047757F7A, 0x9F4D56D5A47B0B33, + 0x822567466AA1174C, 0xB8F5057DEB082FB2, 0xCC48C10BF4475F53, 0x373088D4275DEC3A, + 0x968F4325180AED10, 0x173D232CF7016151, 0xAE4ED09F946FCC13, 0xFD4B4741C4539873, + 0x1B5B3F0DD9933765, 0x2FFCB0967B644052, 0xE02376D20A89840C, 0xA3AE3A70329B18D7, + 0x419CBD2335DE8526, 0xFAFEBF115B7C3199, 0x0397074F85AA9B0D, 0xC58AD4FB4836B970, + 0xBEC60BE3FC4104A8, 0x1EFF36DC4B708772, 0x131FDC33ED8453B6, 0x0844E33E341764D3, + 0x0FF11B6EAB38CD39, 0x64351F0A7761B85A, 0x3B5694F509CFBA0E, 0x30857084B87245D0, + 0x47AFB3BD2297AE3C, 0xF2BA5C2F6F6B554A, 0x74BDC4761F4F70E1, 0xCFDFC64471EDC45E, + 0xE610784C1DC0AF16, 0x7ACA29D63C113F28, 0x2DED411776A859AF, 0xAC5F211E99A3D5EE, + 0xD484F949A87EF33B, 0x3CE36CA596E013E4, 0xD120F0983A9D432C, 0x6BC40464DC597563, + 0x69D5F5E5D1956C9E, 0x9AE95F043698BB24, 0xC9ECC8DA66A4EF44, 0xD69508C8A5B2EAC6, + 0xC40C2235C0503B80, 0x38C193BA8C652103, 0x1CEEC75D46BC9E8F, 0xD331011937515AD1, + 0xD8E2E56886ECA50F, 0xB137108D5779C991, 0x709F3B6905CA4206, 0x4FEB50831680CAEF, + 0xEC456AF3241BD238, 0x58D673AFE181ABBE, 0x242F54E7CAD9BF8C, 0x0211F1810DCC19FD, + 0x90BC4DBB0F43C60A, 0x9518446A9DA0761D, 0xA1BFCBF13F57012A, 0x2BDE4F8961E172B5, + 0x27B853A84F732481, 0xB0B1E643DF1F4B61, 0x18CC38425C39AC68, 0xD2B7F7D7BF37D821, + 0x3103864A3014C720, 0x14AA246372ABFA5C, 0x6E600DB54EBAC574, 0x394765740403A3F3, + 0x09C215F0BC71E623, 0x2A58B947E987F045, 0x7B4CDF18B477BDD8, 0x9709B5EB906C6FE0, + 0x73083C268060D90B, 0xFEDC400E41F9037E, 0x284948C6E44BE9B8, 0x728ECAE808065BFB, + 0x06330E9E17492B1A, 0x5950856169E7294E, 0xBAE4F4FCE6C4364F, 0xCA7BCF95E30E7449, + 0x7D7FD186A33E96C2, 0x52836110D85AD690, 0x4DFAA1021B4CD312, 0x913ABB75872544FA, + 0xDD46ECB9140F1518, 0x3D659A6B1E869114, 0xC23F2CABD719109A, 0xD713FE062DD46836, + 0xD0A60656B2FBC1DC, 0x221C5A79DD909496, 0xEFD26DBCA1B14935, 0x0E77EDA0235E4FC9, + 0xCBFD395B6B68F6B9, 0x0DE0EAEFA6F4D4C4, 0x0422FF1F1A8532E7, 0xF969B85EDED6AA94, + 0x7F6E2007AEF28F3F, 0x3AD0623B81A938FE, 0x6624EE8B7AADA1A7, 0xB682E8DDC856607B, + 0xA78CC56F281E2A30, 0xC79B257A45FAA08D, 0x5B4174E0642B30B3, 0x5F638BFF7EAE0254, + 0x4BC9AF9C0C05F808, 0xCE59308AF98B46AE, 0x8FC58DA9CC55C388, 0x803496C7676D0EB1, + 0xF33CAAE1E70DD7BA, 0xBB6202326EA2B4BF, 0xD5020F87201871CB, 0x9D5CA754A9B712CE, + 0x841669D87DE83C56, 0x8A6184785EB6739F, 0x420BBA6CB0741E2B, 0xF12D5B60EAC1CE47, + 0x76AC35F71283691C, 0x2C6BB7D9FECEDB5F, 0xFCCDB18F4C351A83, 0x1F79C012C3160582, + 0xF0ABADAE62A74CB7, 0xE1A5801C82EF06FC, 0x67A21845F2CB2357, 0x5114665F5DF04D9D, + 0xBF40FD2D74278658, 0xA0393D3FB73183DA, 0x05A409D192E3B017, 0xA9FB28CF0B4065F9, + 0x25A9A22942BF3D7C, 0xDB75E22703463E02, 0xB326E10C5AB5D06C, 0xE7968E8295A62DE6, + 0xB973F3B3636EAD42, 0xDF571D3819C30CE5, 0xEE549B7229D7CBC5, 0x12992AFD65E2D146, + 0xF8EF4E9056B02864, 0xB7041E134030E28B, 0xC02EDD2ADAD50967, 0x932B4AF48AE95D07, + 0x6FE6FB7BC6DC4784, 0x239AACB755F61666, 0x401A4BEDBDB807D6, 0x485EA8D389AF6305, + 0xA41BC220ADB4B13D, 0x753B32B89729F211, 0x997E584BB3322029, 0x1D683193CEDA1C7F, + 0xFF5AB6C0C99F818E, 0x16BBD5E27F67E3A1, 0xA59D34EE25D233CD, 0x98F8AE853B54A2D9, + 0x6DF70AFACB105E79, 0x795D2E99B9BBA425, 0x8E437B6744334178, 0x0186F6CE886682F0, + 0xEBF092A3BB347BD2, 0xBCD7FA62F18D1D55, 0xADD9D7D011C5571E, 0x0BD3E471B1BDFFDE, + 0xAA6C2F808EEAFEF4, 0x5EE57D31F6C880A4, 0xF50FA47FF044FCA0, 0x1ADDC9C351F5B595, + 0xEA76646D3352F922, 0x0000000000000000, 0x85909F16F58EBEA6, 0x46294573AAF12CCC, + 0x0A5512BF39DB7D2E, 0x78DBD85731DD26D5, 0x29CFBE086C2D6B48, 0x218B5D36583A0F9B, + 0x152CD2ADFACD78AC, 0x83A39188E2C795BC, 0xC3B9DA655F7F926A, 0x9ECBA01B2C1D89C3, + 0x07B5F8509F2FA9EA, 0x7EE8D6C926940DCF, 0x36B67E1AAF3B6ECA, 0x86079859702425AB, + 0xFB7849DFD31AB369, 0x4C7C57CC932A51E2, 0xD96413A60E8A27FF, 0x263EA566C715A671, + 0x6C71FC344376DC89, 0x4A4F595284637AF8, 0xDAF314E98B20BCF2, 0x572768C14AB96687, + 0x1088DB7C682EC8BB, 0x887075F9537A6A62, 0x2E7A4658F302C2A2, 0x619116DBE582084D, + 0xA87DDE018326E709, 0xDCC01A779C6997E8, 0xEDC39C3DAC7D50C8, 0xA60A33A1A078A8C0, + 0xC1A82BE452B38B97, 0x3F746BEA134A88E9, 0xA228CCBEBAFD9A27, 0xABEAD94E068C7C04, + 0xF48952B178227E50, 0x5CF48CB0FB049959, 0x6017E0156DE48ABD, 0x4438B4F2A73D3531, + 0x8C528AE649FF5885, 0xB515EF924DFCFB76, 0x0C661C212E925634, 0xB493195CC59A7986, + 0x9CDA519A21D1903E, 0x32948105B5BE5C2D, 0x194ACE8CD45F2E98, 0x438D4CA238129CDB, + 0x9B6FA9CABEFE39D4, 0x81B26009EF0B8C41, 0xDED1EBF691A58E15, 0x4E6DA64D9EE6481F, + 0x54B06F8ECF13FD8A, 0x49D85E1D01C9E1F5, 0xAFC826511C094EE3, 0xF698A33075EE67AD, + 0x5AC7822EEC4DB243, 0x8DD47C28C199DA75, 0x89F68337DB1CE892, 0xCDCE37C57C21DDA3, + 0x530597DE503C5460, 0x6A42F2AA543FF793, 0x5D727A7E73621BA9, 0xE232875307459DF1, + 0x56A19E0FC2DFE477, 0xC61DD3B4CD9C227D, 0xE5877F03986A341B, 0x949EB2A415C6F4ED, + 0x6206119460289340, 0x6380E75AE84E11B0, 0x8BE772B6D6D0F16F, 0x50929091D596CF6D, + 0xE86795EC3E9EE0DF, 0x7CF927482B581432, 0xC86A3E14EEC26DB4, 0x7119CDA78DACC0F6, + 0xE40189CD100CB6EB, 0x92ADBC3A028FDFF7, 0xB2A017C2D2D3529C, 0x200DABF8D05C8D6B, + 0x34A78F9BA2F77737, 0xE3B4719D8F231F01, 0x45BE423C2F5BB7C1, 0xF71E55FEFD88E55D, + 0x6853032B59F3EE6E, 0x65B3E9C4FF073AAA, 0x772AC3399AE5EBEC, 0x87816E97F842A75B, + 0x110E2DB2E0484A4B, 0x331277CB3DD8DEDD, 0xBD510CAC79EB9FA5, 0x352179552A91F5C7 + }; + static const uint64_t T5[256] = + { + 0x8AB0A96846E06A6D, 0x43C7E80B4BF0B33A, 0x08C9B3546B161EE5, 0x39F1C235EBA990BE, + 0xC1BEF2376606C7B2, 0x2C209233614569AA, 0xEB01523B6FC3289A, 0x946953AB935ACEDD, + 0x272838F63E13340E, 0x8B0455ECA12BA052, 0x77A1B2C4978FF8A2, 0xA55122CA13E54086, + 0x2276135862D3F1CD, 0xDB8DDFDE08B76CFE, 0x5D1E12C89E4A178A, 0x0E56816B03969867, + 0xEE5F79953303ED59, 0xAFED748BAB78D71D, 0x6D929F2DF93E53EE, 0xF5D8A8F8BA798C2A, + 0xF619B1698E39CF6B, 0x95DDAF2F749104E2, 0xEC2A9C80E0886427, 0xCE5C8FD8825B95EA, + 0xC4E0D9993AC60271, 0x4699C3A5173076F9, 0x3D1B151F50A29F42, 0x9ED505EA2BC75946, + 0x34665ACFDC7F4B98, 0x61B1FB53292342F7, 0xC721C0080E864130, 0x8693CD1696FD7B74, + 0x872731927136B14B, 0xD3446C8A63A1721B, 0x669A35E8A6680E4A, 0xCAB658F239509A16, + 0xA4E5DE4EF42E8AB9, 0x37A7435EE83F08D9, 0x134E6239E26C7F96, 0x82791A3C2DF67488, + 0x3F6EF00A8329163C, 0x8E5A7E42FDEB6591, 0x5CAAEE4C7981DDB5, 0x19F234785AF1E80D, + 0x255DDDE3ED98BD70, 0x50898A32A99CCCAC, 0x28CA4519DA4E6656, 0xAE59880F4CB31D22, + 0x0D9798FA37D6DB26, 0x32F968F0B4FFCD1A, 0xA00F09644F258545, 0xFA3AD5175E24DE72, + 0xF46C547C5DB24615, 0x713E80FBFF0F7E20, 0x7843CF2B73D2AAFA, 0xBD17EA36AEDF62B4, + 0xFD111BACD16F92CF, 0x4ABAA7DBC72D67E0, 0xB3416B5DAD49FAD3, 0xBCA316B24914A88B, + 0x15D150068AECF914, 0xE27C1DEBE31EFC40, 0x4FE48C759BEDA223, 0x7EDCFD141B522C78, + 0x4E5070F17C26681C, 0xE696CAC15815F3BC, 0x35D2A64B3BB481A7, 0x800CFF29FE7DFDF6, + 0x1ED9FAC3D5BAA4B0, 0x6C2663A91EF599D1, 0x03C1199134404341, 0xF7AD4DED69F20554, + 0xCD9D9649B61BD6AB, 0xC8C3BDE7EADB1368, 0xD131899FB02AFB65, 0x1D18E352E1FAE7F1, + 0xDA39235AEF7CA6C1, 0xA1BBF5E0A8EE4F7A, 0x91377805CF9A0B1E, 0x3138716180BF8E5B, + 0xD9F83ACBDB3CE580, 0x0275E515D38B897E, 0x472D3F21F0FBBCC6, 0x2D946EB7868EA395, + 0xBA3C248D21942E09, 0xE7223645BFDE3983, 0xFF64FEB902E41BB1, 0xC97741630D10D957, + 0xC3CB1722B58D4ECC, 0xA27AEC719CAE0C3B, 0x99FECB51A48C15FB, 0x1465AC826D27332B, + 0xE1BD047AD75EBF01, 0x79F733AF941960C5, 0x672EC96C41A3C475, 0xC27FEBA6524684F3, + 0x64EFD0FD75E38734, 0xED9E60040743AE18, 0xFB8E2993B9EF144D, 0x38453EB10C625A81, + 0x6978480742355C12, 0x48CF42CE14A6EE9E, 0x1CAC1FD606312DCE, 0x7B82D6BA4792E9BB, + 0x9D141C7B1F871A07, 0x5616B80DC11C4A2E, 0xB849C198F21FA777, 0x7CA91801C8D9A506, + 0xB1348E487EC273AD, 0x41B20D1E987B3A44, 0x7460AB55A3CFBBE3, 0x84E628034576F20A, + 0x1B87D16D897A6173, 0x0FE27DEFE45D5258, 0x83CDE6B8CA3DBEB7, 0x0C23647ED01D1119, + 0x7A362A3EA0592384, 0xB61F40F3F1893F10, 0x75D457D1440471DC, 0x4558DA34237035B8, + 0xDCA6116587FC2043, 0x8D9B67D3C9AB26D0, 0x2B0B5C88EE0E2517, 0x6FE77A382AB5DA90, + 0x269CC472D9D8FE31, 0x63C41E46FAA8CB89, 0xB7ABBC771642F52F, 0x7D1DE4852F126F39, + 0xA8C6BA3024339BA0, 0x600507D7CEE888C8, 0x8FEE82C61A20AFAE, 0x57A2448926D78011, + 0xFCA5E72836A458F0, 0x072BCEBB8F4B4CBD, 0x497BBE4AF36D24A1, 0x3CAFE99BB769557D, + 0x12FA9EBD05A7B5A9, 0xE8C04BAA5B836BDB, 0x4273148FAC3B7905, 0x908384812851C121, + 0xE557D3506C55B0FD, 0x72FF996ACB4F3D61, 0x3EDA0C8E64E2DC03, 0xF0868356E6B949E9, + 0x04EAD72ABB0B0FFC, 0x17A4B5135967706A, 0xE3C8E16F04D5367F, 0xF84F30028DAF570C, + 0x1846C8FCBD3A2232, 0x5B8120F7F6CA9108, 0xD46FA231ECEA3EA6, 0x334D947453340725, + 0x58403966C28AD249, 0xBED6F3A79A9F21F5, 0x68CCB483A5FE962D, 0xD085751B57E1315A, + 0xFED0023DE52FD18E, 0x4B0E5B5F20E6ADDF, 0x1A332DE96EB1AB4C, 0xA3CE10F57B65C604, + 0x108F7BA8D62C3CD7, 0xAB07A3A11073D8E1, 0x6B0DAD1291BED56C, 0xF2F366433532C097, + 0x2E557726B2CEE0D4, 0x0000000000000000, 0xCB02A476DE9B5029, 0xE4E32FD48B9E7AC2, + 0x734B65EE2C84F75E, 0x6E5386BCCD7E10AF, 0x01B4FC84E7CBCA3F, 0xCFE8735C65905FD5, + 0x3613BFDA0FF4C2E6, 0x113B872C31E7F6E8, 0x2FE18BA255052AEB, 0xE974B72EBC48A1E4, + 0x0ABC5641B89D979B, 0xB46AA5E62202B66E, 0x44EC26B0C4BBFF87, 0xA6903B5B27A503C7, + 0x7F680190FC99E647, 0x97A84A3AA71A8D9C, 0xDD12EDE16037EA7C, 0xC554251DDD0DC84E, + 0x88C54C7D956BE313, 0x4D91696048662B5D, 0xB08072CC9909B992, 0xB5DE5962C5C97C51, + 0x81B803AD19B637C9, 0xB2F597D94A8230EC, 0x0B08AAC55F565DA4, 0xF1327FD2017283D6, + 0xAD98919E78F35E63, 0x6AB9519676751F53, 0x24E921670A53774F, 0xB9FD3D1C15D46D48, + 0x92F66194FBDA485F, 0x5A35DC7311015B37, 0xDED3F4705477A93D, 0xC00A0EB381CD0D8D, + 0xBB88D809C65FE436, 0x16104997BEACBA55, 0x21B70AC95693B28C, 0x59F4C5E225411876, + 0xD5DB5EB50B21F499, 0x55D7A19CF55C096F, 0xA97246B4C3F8519F, 0x8552D487A2BD3835, + 0x54635D181297C350, 0x23C2EFDC85183BF2, 0x9F61F96ECC0C9379, 0x534893A39DDC8FED, + 0x5EDF0B59AA0A54CB, 0xAC2C6D1A9F38945C, 0xD7AEBBA0D8AA7DE7, 0x2ABFA00C09C5EF28, + 0xD84CC64F3CF72FBF, 0x2003F64DB15878B3, 0xA724C7DFC06EC9F8, 0x069F323F68808682, + 0xCC296ACD51D01C94, 0x055E2BAE5CC0C5C3, 0x6270E2C21D6301B6, 0x3B842720382219C0, + 0xD2F0900E846AB824, 0x52FC6F277A1745D2, 0xC6953C8CE94D8B0F, 0xE009F8FE3095753E, + 0x655B2C7992284D0B, 0x984A37D54347DFC4, 0xEAB5AEBF8808E2A5, 0x9A3FD2C090CC56BA, + 0x9CA0E0FFF84CD038, 0x4C2595E4AFADE162, 0xDF6708F4B3BC6302, 0xBF620F237D54EBCA, + 0x93429D101C118260, 0x097D4FD08CDDD4DA, 0x8C2F9B572E60ECEF, 0x708A7C7F18C4B41F, + 0x3A30DBA4DFE9D3FF, 0x4006F19A7FB0F07B, 0x5F6BF7DD4DC19EF4, 0x1F6D064732716E8F, + 0xF9FBCC866A649D33, 0x308C8DE567744464, 0x8971B0F972A0292C, 0xD61A47243F61B7D8, + 0xEFEB8511D4C82766, 0x961CB6BE40D147A3, 0xAAB35F25F7B812DE, 0x76154E407044329D, + 0x513D76B64E570693, 0xF3479AC7D2F90AA8, 0x9B8B2E4477079C85, 0x297EB99D3D85AC69 + }; + static const uint64_t T6[256] = + { + 0x7E37E62DFC7D40C3, 0x776F25A4EE939E5B, 0xE045C850DD8FB5AD, 0x86ED5BA711FF1952, + 0xE91D0BD9CF616B35, 0x37E0AB256E408FFB, 0x9607F6C031025A7A, 0x0B02F5E116D23C9D, + 0xF3D8486BFB50650C, 0x621CFF27C40875F5, 0x7D40CB71FA5FD34A, 0x6DAA6616DAA29062, + 0x9F5F354923EC84E2, 0xEC847C3DC507C3B3, 0x025A3668043CE205, 0xA8BF9E6C4DAC0B19, + 0xFA808BE2E9BEBB94, 0xB5B99C5277C74FA3, 0x78D9BC95F0397BCC, 0xE332E50CDBAD2624, + 0xC74FCE129332797E, 0x1729ECEB2EA709AB, 0xC2D6B9F69954D1F8, 0x5D898CBFBAB8551A, + 0x859A76FB17DD8ADB, 0x1BE85886362F7FB5, 0xF6413F8FF136CD8A, 0xD3110FA5BBB7E35C, + 0x0A2FEED514CC4D11, 0xE83010EDCD7F1AB9, 0xA1E75DE55F42D581, 0xEEDE4A55C13B21B6, + 0xF2F5535FF94E1480, 0x0CC1B46D1888761E, 0xBCE15FDB6529913B, 0x2D25E8975A7181C2, + 0x71817F1CE2D7A554, 0x2E52C5CB5C53124B, 0xF9F7A6BEEF9C281D, 0x9E722E7D21F2F56E, + 0xCE170D9B81DCA7E6, 0x0E9B82051CB4941B, 0x1E712F623C49D733, 0x21E45CFA42F9F7DC, + 0xCB8E7A7F8BBA0F60, 0x8E98831A010FB646, 0x474CCF0D8E895B23, 0xA99285584FB27A95, + 0x8CC2B57205335443, 0x42D5B8E984EFF3A5, 0x012D1B34021E718C, 0x57A6626AAE74180B, + 0xFF19FC06E3D81312, 0x35BA9D4D6A7C6DFE, 0xC9D44C178F86ED65, 0x506523E6A02E5288, + 0x03772D5C06229389, 0x8B01F4FE0B691EC0, 0xF8DABD8AED825991, 0x4C4E3AEC985B67BE, + 0xB10DF0827FBF96A9, 0x6A69279AD4F8DAE1, 0xE78689DCD3D5FF2E, 0x812E1A2B1FA553D1, + 0xFBAD90D6EBA0CA18, 0x1AC543B234310E39, 0x1604F7DF2CB97827, 0xA6241C6951189F02, + 0x753513CCEAAF7C5E, 0x64F2A59FC84C4EFA, 0x247D2B1E489F5F5A, 0xDB64D718AB474C48, + 0x79F4A7A1F2270A40, 0x1573DA832A9BEBAE, 0x3497867968621C72, 0x514838D2A2302304, + 0xF0AF6537FD72F685, 0x1D06023E3A6B44BA, 0x678588C3CE6EDD73, 0x66A893F7CC70ACFF, + 0xD4D24E29B5EDA9DF, 0x3856321470EA6A6C, 0x07C3418C0E5A4A83, 0x2BCBB22F5635BACD, + 0x04B46CD00878D90A, 0x06EE5AB80C443B0F, 0x3B211F4876C8F9E5, 0x0958C38912EEDE98, + 0xD14B39CDBF8B0159, 0x397B292072F41BE0, 0x87C0409313E168DE, 0xAD26E98847CAA39F, + 0x4E140C849C6785BB, 0xD5FF551DB7F3D853, 0xA0CA46D15D5CA40D, 0xCD6020C787FE346F, + 0x84B76DCF15C3FB57, 0xDEFDA0FCA121E4CE, 0x4B8D7B6096012D3D, 0x9AC642AD298A2C64, + 0x0875D8BD10F0AF14, 0xB357C6EA7B8374AC, 0x4D6321D89A451632, 0xEDA96709C719B23F, + 0xF76C24BBF328BC06, 0xC662D526912C08F2, 0x3CE25EC47892B366, 0xB978283F6F4F39BD, + 0xC08C8F9E9D6833FD, 0x4F3917B09E79F437, 0x593DE06FB2C08C10, 0xD6887841B1D14BDA, + 0x19B26EEE32139DB0, 0xB494876675D93E2F, 0x825937771987C058, 0x90E9AC783D466175, + 0xF1827E03FF6C8709, 0x945DC0A8353EB87F, 0x4516F9658AB5B926, 0x3F9573987EB020EF, + 0xB855330B6D514831, 0x2AE6A91B542BCB41, 0x6331E413C6160479, 0x408F8E8180D311A0, + 0xEFF35161C325503A, 0xD06622F9BD9570D5, 0x8876D9A20D4B8D49, 0xA5533135573A0C8B, + 0xE168D364DF91C421, 0xF41B09E7F50A2F8F, 0x12B09B0F24C1A12D, 0xDA49CC2CA9593DC4, + 0x1F5C34563E57A6BF, 0x54D14F36A8568B82, 0xAF7CDFE043F6419A, 0xEA6A2685C943F8BC, + 0xE5DCBFB4D7E91D2B, 0xB27ADDDE799D0520, 0x6B443CAED6E6AB6D, 0x7BAE91C9F61BE845, + 0x3EB868AC7CAE5163, 0x11C7B65322E332A4, 0xD23C1491B9A992D0, 0x8FB5982E0311C7CA, + 0x70AC6428E0C9D4D8, 0x895BC2960F55FCC5, 0x76423E90EC8DEFD7, 0x6FF0507EDE9E7267, + 0x3DCF45F07A8CC2EA, 0x4AA06054941F5CB1, 0x5810FB5BB0DEFD9C, 0x5EFEA1E3BC9AC693, + 0x6EDD4B4ADC8003EB, 0x741808F8E8B10DD2, 0x145EC1B728859A22, 0x28BC9F7350172944, + 0x270A06424EBDCCD3, 0x972AEDF4331C2BF6, 0x059977E40A66A886, 0x2550302A4A812ED6, + 0xDD8A8DA0A7037747, 0xC515F87A970E9B7B, 0x3023EAA9601AC578, 0xB7E3AA3A73FBADA6, + 0x0FB699311EAAE597, 0x0000000000000000, 0x310EF19D6204B4F4, 0x229371A644DB6455, + 0x0DECAF591A960792, 0x5CA4978BB8A62496, 0x1C2B190A38753536, 0x41A295B582CD602C, + 0x3279DCC16426277D, 0xC1A194AA9F764271, 0x139D803B26DFD0A1, 0xAE51C4D441E83016, + 0xD813FA44AD65DFC1, 0xAC0BF2BC45D4D213, 0x23BE6A9246C515D9, 0x49D74D08923DCF38, + 0x9D05032127D066E7, 0x2F7FDEFF5E4D63C7, 0xA47E2A0155247D07, 0x99B16FF12FA8BFED, + 0x4661D4398C972AAF, 0xDFD0BBC8A33F9542, 0xDCA79694A51D06CB, 0xB020EBB67DA1E725, + 0xBA0F0563696DAA34, 0xE4F1A480D5F76CA7, 0xC438E34E9510EAF7, 0x939E81243B64F2FC, + 0x8DEFAE46072D25CF, 0x2C08F3A3586FF04E, 0xD7A56375B3CF3A56, 0x20C947CE40E78650, + 0x43F8A3DD86F18229, 0x568B795EAC6A6987, 0x8003011F1DBB225D, 0xF53612D3F7145E03, + 0x189F75DA300DEC3C, 0x9570DB9C3720C9F3, 0xBB221E576B73DBB8, 0x72F65240E4F536DD, + 0x443BE25188ABC8AA, 0xE21FFE38D9B357A8, 0xFD43CA6EE7E4F117, 0xCAA3614B89A47EEC, + 0xFE34E732E1C6629E, 0x83742C431B99B1D4, 0xCF3A16AF83C2D66A, 0xAAE5A8044990E91C, + 0x26271D764CA3BD5F, 0x91C4B74C3F5810F9, 0x7C6DD045F841A2C6, 0x7F1AFD19FE63314F, + 0xC8F957238D989CE9, 0xA709075D5306EE8E, 0x55FC5402AA48FA0E, 0x48FA563C9023BEB4, + 0x65DFBEABCA523F76, 0x6C877D22D8BCE1EE, 0xCC4D3BF385E045E3, 0xBEBB69B36115733E, + 0x10EAAD6720FD4328, 0xB6CEB10E71E5DC2A, 0xBDCC44EF6737E0B7, 0x523F158EA412B08D, + 0x989C74C52DB6CE61, 0x9BEB59992B945DE8, 0x8A2CEFCA09776F4C, 0xA3BD6B8D5B7E3784, + 0xEB473DB1CB5D8930, 0xC3FBA2C29B4AA074, 0x9C28181525CE176B, 0x683311F2D0C438E4, + 0x5FD3BAD7BE84B71F, 0xFC6ED15AE5FA809B, 0x36CDB0116C5EFE77, 0x29918447520958C8, + 0xA29070B959604608, 0x53120EBAA60CC101, 0x3A0C047C74D68869, 0x691E0AC6D2DA4968, + 0x73DB4974E6EB4751, 0x7A838AFDF40599C9, 0x5A4ACD33B4E21F99, 0x6046C94FC03497F0, + 0xE6AB92E8D1CB8EA2, 0x3354C7F5663856F1, 0xD93EE170AF7BAE4D, 0x616BD27BC22AE67C, + 0x92B39A10397A8370, 0xABC8B3304B8E9890, 0xBF967287630B02B2, 0x5B67D607B6FC6E15 + }; + static uint64_t T7[256] = + { + 0xD031C397CE553FE6, 0x16BA5B01B006B525, 0xA89BADE6296E70C8, 0x6A1F525D77D3435B, + 0x6E103570573DFA0B, 0x660EFB2A17FC95AB, 0x76327A9E97634BF6, 0x4BAD9D6462458BF5, + 0xF1830CAEDBC3F748, 0xC5C8F542669131FF, 0x95044A1CDC48B0CB, 0x892962DF3CF8B866, + 0xB0B9E208E930C135, 0xA14FB3F0611A767C, 0x8D2605F21C160136, 0xD6B71922FECC549E, + 0x37089438A5907D8B, 0x0B5DA38E5803D49C, 0x5A5BCC9CEA6F3CBC, 0xEDAE246D3B73FFE5, + 0xD2B87E0FDE22EDCE, 0x5E54ABB1CA8185EC, 0x1DE7F88FE80561B9, 0xAD5E1A870135A08C, + 0x2F2ADBD665CECC76, 0x5780B5A782F58358, 0x3EDC8A2EEDE47B3F, 0xC9D95C3506BEE70F, + 0x83BE111D6C4E05EE, 0xA603B90959367410, 0x103C81B4809FDE5D, 0x2C69B6027D0C774A, + 0x399080D7D5C87953, 0x09D41E16487406B4, 0xCDD63B1826505E5F, 0xF99DC2F49B0298E8, + 0x9CD0540A943CB67F, 0xBCA84B7F891F17C5, 0x723D1DB3B78DF2A6, 0x78AA6E71E73B4F2E, + 0x1433E699A071670D, 0x84F21BE454620782, 0x98DF3327B4D20F2F, 0xF049DCE2D3769E5C, + 0xDB6C60199656EB7A, 0x648746B2078B4783, 0x32CD23598DCBADCF, 0x1EA4955BF0C7DA85, + 0xE9A143401B9D46B5, 0xFD92A5D9BBEC21B8, 0xC8138C790E0B8E1B, 0x2EE00B9A6D7BA562, + 0xF85712B893B7F1FC, 0xEB28FED80BEA949D, 0x564A65EB8A40EA4C, 0x6C9988E8474A2823, + 0x4535898B121D8F2D, 0xABD8C03231ACCBF4, 0xBA2E91CAB9867CBD, 0x7960BE3DEF8E263A, + 0x0C11A977602FD6F0, 0xCB50E1AD16C93527, 0xEAE22E94035FFD89, 0x2866D12F5DE2CE1A, + 0xFF1B1841AB9BF390, 0x9F9339DE8CFE0D43, 0x964727C8C48A0BF7, 0x524502C6AAAE531C, + 0x9B9C5EF3AC10B413, 0x4FA2FA4942AB32A5, 0x3F165A62E551122B, 0xC74148DA76E6E3D7, + 0x924840E5E464B2A7, 0xD372AE43D69784DA, 0x233B72A105E11A86, 0xA48A04914941A638, + 0xB4B68525C9DE7865, 0xDDEABAACA6CF8002, 0x0A9773C250B6BD88, 0xC284FFBB5EBD3393, + 0x8BA0DF472C8F6A4E, 0x2AEF6CB74D951C32, 0x427983722A318D41, 0x73F7CDFFBF389BB2, + 0x074C0AF9382C026C, 0x8A6A0F0B243A035A, 0x6FDAE53C5F88931F, 0xC68B98967E538AC3, + 0x44FF59C71AA8E639, 0xE2FCE0CE439E9229, 0xA20CDE2479D8CD40, 0x19E89FA2C8EBD8E9, + 0xF446BBCFF398270C, 0x43B3533E2284E455, 0xD82F0DCD8E945046, 0x51066F12B26CE820, + 0xE73957AF6BC5426D, 0x081ECE5A40C16FA0, 0x3B193D4FC5BFAB7B, 0x7FE66488DF174D42, + 0x0E9814EF705804D8, 0x8137AC857C39D7C6, 0xB1733244E185A821, 0x695C3F896F11F867, + 0xF6CF0657E3EFF524, 0x1AABF276D02963D5, 0x2DA3664E75B91E5E, 0x0289BD981077D228, + 0x90C1FD7DF413608F, 0x3C5537B6FD93A917, 0xAA12107E3919A2E0, 0x0686DAB530996B78, + 0xDAA6B0559EE3826E, 0xC34E2FF756085A87, 0x6D5358A44FFF4137, 0xFC587595B35948AC, + 0x7CA5095CC7D5F67E, 0xFB147F6C8B754AC0, 0xBFEB26AB91DDACF9, 0x6896EFC567A49173, + 0xCA9A31E11E7C5C33, 0xBBE44186B13315A9, 0x0DDB793B689ABFE4, 0x70B4A02BA7FA208E, + 0xE47A3A7B7307F951, 0x8CECD5BE14A36822, 0xEEED49B923B144D9, 0x17708B4DB8B3DC31, + 0x6088219F2765FED3, 0xB3FA8FDCF1F27A09, 0x910B2D31FCA6099B, 0x0F52C4A378ED6DCC, + 0x50CCBF5EBAD98134, 0x6BD582117F662A4F, 0x94CE9A50D4FDD9DF, 0x2B25BCFB45207526, + 0x67C42B661F49FCBF, 0x492420FC723259DD, 0x03436DD418C2BB3C, 0x1F6E4517F872B391, + 0xA08563BC69AF1F68, 0xD43EA4BAEEBB86B6, 0x01CAD04C08B56914, 0xAC94CACB0980C998, + 0x54C3D8739A373864, 0x26FEC5C02DBACAC2, 0xDEA9D778BE0D3B3E, 0x040F672D20EEB950, + 0xE5B0EA377BB29045, 0xF30AB136CBB42560, 0x62019C0737122CFB, 0xE86B930C13282FA1, + 0xCC1CEB542EE5374B, 0x538FD28AA21B3A08, 0x1B61223AD89C0AC1, 0x36C24474AD25149F, + 0x7A23D3E9F74C9D06, 0xBE21F6E79968C5ED, 0xCF5F868036278C77, 0xF705D61BEB5A9C30, + 0x4D2B47D152DCE08D, 0x5F9E7BFDC234ECF8, 0x247778583DCD18EA, 0x867BA67C4415D5AA, + 0x4CE1979D5A698999, 0x0000000000000000, 0xEC64F42133C696F1, 0xB57C5569C16B1171, + 0xC1C7926F467F88AF, 0x654D96FE0F3E2E97, 0x15F936D5A8C40E19, 0xB8A72C52A9F1AE95, + 0xA9517DAA21DB19DC, 0x58D27104FA18EE94, 0x5918A148F2AD8780, 0x5CDD1629DAF657C4, + 0x8274C15164FB6CFA, 0xD1FB13DBC6E056F2, 0x7D6FD910CF609F6A, 0xB63F38BDD9A9AA4D, + 0x3D9FE7FAF526C003, 0x74BBC706871499DE, 0xDF630734B6B8522A, 0x3AD3ED03CD0AC26F, + 0xFADEAF2083C023D4, 0xC00D42234ECAE1BB, 0x8538CBA85CD76E96, 0xC402250E6E2458EB, + 0x47BC3413026A5D05, 0xAFD7A71F114272A4, 0x978DF784CC3F62E3, 0xB96DFC1EA144C781, + 0x21B2CF391596C8AE, 0x318E4E8D950916F3, 0xCE9556CC3E92E563, 0x385A509BDD7D1047, + 0x358129A0B5E7AFA3, 0xE6F387E363702B79, 0xE0755D5653E94001, 0x7BE903A5FFF9F412, + 0x12B53C2C90E80C75, 0x3307F315857EC4DB, 0x8FAFB86A0C61D31E, 0xD9E5DD8186213952, + 0x77F8AAD29FD622E2, 0x25BDA814357871FE, 0x7571174A8FA1F0CA, 0x137FEC60985D6561, + 0x30449EC19DBC7FE7, 0xA540D4DD41F4CF2C, 0xDC206AE0AE7AE916, 0x5B911CD0E2DA55A8, + 0xB2305F90F947131D, 0x344BF9ECBD52C6B7, 0x5D17C665D2433ED0, 0x18224FEEC05EB1FD, + 0x9E59E992844B6457, 0x9A568EBFA4A5DD07, 0xA3C60E68716DA454, 0x7E2CB4C4D7A22456, + 0x87B176304CA0BCBE, 0x413AEEA632F3367D, 0x9915E36BBC67663B, 0x40F03EEA3A465F69, + 0x1C2D28C3E0B008AD, 0x4E682A054A1E5BB1, 0x05C5B761285BD044, 0xE1BF8D1A5B5C2915, + 0xF2C0617AC3014C74, 0xB7F5E8F1D11CC359, 0x63CB4C4B3FA745EF, 0x9D1A84469C89DF6B, + 0xE33630824B2BFB3D, 0xD5F474F6E60EEFA2, 0xF58C6B83FB2D4E18, 0x4676E45F0ADF3411, + 0x20781F751D23A1BA, 0xBD629B3381AA7ED1, 0xAE1D775319F71BB0, 0xFED1C80DA32E9A84, + 0x5509083F92825170, 0x29AC01635557A70E, 0xA7C9694551831D04, 0x8E65682604D4BA0A, + 0x11F651F8882AB749, 0xD77DC96EF6793D8A, 0xEF2799F52B042DCD, 0x48EEF0B07A8730C9, + 0x22F1A2ED0D547392, 0x6142F1D32FD097C7, 0x4A674D286AF0E2E1, 0x80FD7CC9748CBED2, + 0x717E7067AF4F499A, 0x938290A9ECD1DBB3, 0x88E3B293344DD172, 0x2734158C250FA3D6 }; - static const uint64_t A_[64] = - { - 0x8e20faa72ba0b470, 0x47107ddd9b505a38, 0xad08b0e0c3282d1c, 0xd8045870ef14980e, - 0x6c022c38f90a4c07, 0x3601161cf205268d, 0x1b8e0b0e798c13c8, 0x83478b07b2468764, - 0xa011d380818e8f40, 0x5086e740ce47c920, 0x2843fd2067adea10, 0x14aff010bdd87508, - 0x0ad97808d06cb404, 0x05e23c0468365a02, 0x8c711e02341b2d01, 0x46b60f011a83988e, - 0x90dab52a387ae76f, 0x486dd4151c3dfdb9, 0x24b86a840e90f0d2, 0x125c354207487869, - 0x092e94218d243cba, 0x8a174a9ec8121e5d, 0x4585254f64090fa0, 0xaccc9ca9328a8950, - 0x9d4df05d5f661451, 0xc0a878a0a1330aa6, 0x60543c50de970553, 0x302a1e286fc58ca7, - 0x18150f14b9ec46dd, 0x0c84890ad27623e0, 0x0642ca05693b9f70, 0x0321658cba93c138, - 0x86275df09ce8aaa8, 0x439da0784e745554, 0xafc0503c273aa42a, 0xd960281e9d1d5215, - 0xe230140fc0802984, 0x71180a8960409a42, 0xb60c05ca30204d21, 0x5b068c651810a89e, - 0x456c34887a3805b9, 0xac361a443d1c8cd2, 0x561b0d22900e4669, 0x2b838811480723ba, - 0x9bcf4486248d9f5d, 0xc3e9224312c8c1a0, 0xeffa11af0964ee50, 0xf97d86d98a327728, - 0xe4fa2054a80b329c, 0x727d102a548b194e, 0x39b008152acb8227, 0x9258048415eb419d, - 0x492c024284fbaec0, 0xaa16012142f35760, 0x550b8e9e21f7a530, 0xa48b474f9ef5dc18, - 0x70a6a56e2440598e, 0x3853dc371220a247, 0x1ca76e95091051ad, 0x0edd37c48a08a6d8, - 0x07e095624504536c, 0x8d70c431ac02a736, 0xc83862965601dd1b, 0x641c314b2b8ee083 - }; - - static const uint8_t C_[12][64] = + static const uint64_t C_[12][8] = { { - 0xb1,0x08,0x5b,0xda,0x1e,0xca,0xda,0xe9,0xeb,0xcb,0x2f,0x81,0xc0,0x65,0x7c,0x1f, - 0x2f,0x6a,0x76,0x43,0x2e,0x45,0xd0,0x16,0x71,0x4e,0xb8,0x8d,0x75,0x85,0xc4,0xfc, - 0x4b,0x7c,0xe0,0x91,0x92,0x67,0x69,0x01,0xa2,0x42,0x2a,0x08,0xa4,0x60,0xd3,0x15, - 0x05,0x76,0x74,0x36,0xcc,0x74,0x4d,0x23,0xdd,0x80,0x65,0x59,0xf2,0xa6,0x45,0x07 - }, + 0xe9daca1eda5b08b1, 0x1f7c65c0812fcbeb, 0x16d0452e43766a2f, 0xfcc485758db84e71, + 0x0169679291e07c4b, 0x15d360a4082a42a2, 0x234d74cc36747605, 0x0745a6f2596580dd + }, { - 0x6f,0xa3,0xb5,0x8a,0xa9,0x9d,0x2f,0x1a,0x4f,0xe3,0x9d,0x46,0x0f,0x70,0xb5,0xd7, - 0xf3,0xfe,0xea,0x72,0x0a,0x23,0x2b,0x98,0x61,0xd5,0x5e,0x0f,0x16,0xb5,0x01,0x31, - 0x9a,0xb5,0x17,0x6b,0x12,0xd6,0x99,0x58,0x5c,0xb5,0x61,0xc2,0xdb,0x0a,0xa7,0xca, - 0x55,0xdd,0xa2,0x1b,0xd7,0xcb,0xcd,0x56,0xe6,0x79,0x04,0x70,0x21,0xb1,0x9b,0xb7 - }, + 0x1a2f9da98ab5a36f, 0xd7b5700f469de34f, 0x982b230a72eafef3, 0x3101b5160f5ed561, + 0x5899d6126b17b59a, 0xcaa70adbc261b55c, 0x56cdcbd71ba2dd55, 0xb79bb121700479e6 + }, { - 0xf5,0x74,0xdc,0xac,0x2b,0xce,0x2f,0xc7,0x0a,0x39,0xfc,0x28,0x6a,0x3d,0x84,0x35, - 0x06,0xf1,0x5e,0x5f,0x52,0x9c,0x1f,0x8b,0xf2,0xea,0x75,0x14,0xb1,0x29,0x7b,0x7b, - 0xd3,0xe2,0x0f,0xe4,0x90,0x35,0x9e,0xb1,0xc1,0xc9,0x3a,0x37,0x60,0x62,0xdb,0x09, - 0xc2,0xb6,0xf4,0x43,0x86,0x7a,0xdb,0x31,0x99,0x1e,0x96,0xf5,0x0a,0xba,0x0a,0xb2 - }, + 0xc72fce2bacdc74f5, 0x35843d6a28fc390a, 0x8b1f9c525f5ef106, 0x7b7b29b11475eaf2, + 0xb19e3590e40fe2d3, 0x09db6260373ac9c1, 0x31db7a8643f4b6c2, 0xb20aba0af5961e99 + }, { - 0xef,0x1f,0xdf,0xb3,0xe8,0x15,0x66,0xd2,0xf9,0x48,0xe1,0xa0,0x5d,0x71,0xe4,0xdd, - 0x48,0x8e,0x85,0x7e,0x33,0x5c,0x3c,0x7d,0x9d,0x72,0x1c,0xad,0x68,0x5e,0x35,0x3f, - 0xa9,0xd7,0x2c,0x82,0xed,0x03,0xd6,0x75,0xd8,0xb7,0x13,0x33,0x93,0x52,0x03,0xbe, - 0x34,0x53,0xea,0xa1,0x93,0xe8,0x37,0xf1,0x22,0x0c,0xbe,0xbc,0x84,0xe3,0xd1,0x2e - }, + 0xd26615e8b3df1fef, 0xdde4715da0e148f9, 0x7d3c5c337e858e48, 0x3f355e68ad1c729d, + 0x75d603ed822cd7a9, 0xbe0352933313b7d8, 0xf137e893a1ea5334, 0x2ed1e384bcbe0c22 + }, { - 0x4b,0xea,0x6b,0xac,0xad,0x47,0x47,0x99,0x9a,0x3f,0x41,0x0c,0x6c,0xa9,0x23,0x63, - 0x7f,0x15,0x1c,0x1f,0x16,0x86,0x10,0x4a,0x35,0x9e,0x35,0xd7,0x80,0x0f,0xff,0xbd, - 0xbf,0xcd,0x17,0x47,0x25,0x3a,0xf5,0xa3,0xdf,0xff,0x00,0xb7,0x23,0x27,0x1a,0x16, - 0x7a,0x56,0xa2,0x7e,0xa9,0xea,0x63,0xf5,0x60,0x17,0x58,0xfd,0x7c,0x6c,0xfe,0x57 - }, + 0x994747adac6bea4b, 0x6323a96c0c413f9a, 0x4a1086161f1c157f, 0xbdff0f80d7359e35, + 0xa3f53a254717cdbf, 0x161a2723b700ffdf, 0xf563eaa97ea2567a, 0x57fe6c7cfd581760 + }, { - 0xae,0x4f,0xae,0xae,0x1d,0x3a,0xd3,0xd9,0x6f,0xa4,0xc3,0x3b,0x7a,0x30,0x39,0xc0, - 0x2d,0x66,0xc4,0xf9,0x51,0x42,0xa4,0x6c,0x18,0x7f,0x9a,0xb4,0x9a,0xf0,0x8e,0xc6, - 0xcf,0xfa,0xa6,0xb7,0x1c,0x9a,0xb7,0xb4,0x0a,0xf2,0x1f,0x66,0xc2,0xbe,0xc6,0xb6, - 0xbf,0x71,0xc5,0x72,0x36,0x90,0x4f,0x35,0xfa,0x68,0x40,0x7a,0x46,0x64,0x7d,0x6e - }, + 0xd9d33a1daeae4fae, 0xc039307a3bc3a46f, 0x6ca44251f9c4662d, 0xc68ef09ab49a7f18, + 0xb4b79a1cb7a6facf, 0xb6c6bec2661ff20a, 0x354f903672c571bf, 0x6e7d64467a4068fa + }, { - 0xf4,0xc7,0x0e,0x16,0xee,0xaa,0xc5,0xec,0x51,0xac,0x86,0xfe,0xbf,0x24,0x09,0x54, - 0x39,0x9e,0xc6,0xc7,0xe6,0xbf,0x87,0xc9,0xd3,0x47,0x3e,0x33,0x19,0x7a,0x93,0xc9, - 0x09,0x92,0xab,0xc5,0x2d,0x82,0x2c,0x37,0x06,0x47,0x69,0x83,0x28,0x4a,0x05,0x04, - 0x35,0x17,0x45,0x4c,0xa2,0x3c,0x4a,0xf3,0x88,0x86,0x56,0x4d,0x3a,0x14,0xd4,0x93 - }, + 0xecc5aaee160ec7f4, 0x540924bffe86ac51, 0xc987bfe6c7c69e39, 0xc9937a19333e47d3, + 0x372c822dc5ab9209, 0x04054a2883694706, 0xf34a3ca24c451735, 0x93d4143a4d568688 + }, { - 0x9b,0x1f,0x5b,0x42,0x4d,0x93,0xc9,0xa7,0x03,0xe7,0xaa,0x02,0x0c,0x6e,0x41,0x41, - 0x4e,0xb7,0xf8,0x71,0x9c,0x36,0xde,0x1e,0x89,0xb4,0x44,0x3b,0x4d,0xdb,0xc4,0x9a, - 0xf4,0x89,0x2b,0xcb,0x92,0x9b,0x06,0x90,0x69,0xd1,0x8d,0x2b,0xd1,0xa5,0xc4,0x2f, - 0x36,0xac,0xc2,0x35,0x59,0x51,0xa8,0xd9,0xa4,0x7f,0x0d,0xd4,0xbf,0x02,0xe7,0x1e - }, + 0xa7c9934d425b1f9b, 0x41416e0c02aae703, 0x1ede369c71f8b74e, 0x9ac4db4d3b44b489, + 0x90069b92cb2b89f4, 0x2fc4a5d12b8dd169, 0xd9a8515935c2ac36, 0x1ee702bfd40d7fa4 + }, { - 0x37,0x8f,0x5a,0x54,0x16,0x31,0x22,0x9b,0x94,0x4c,0x9a,0xd8,0xec,0x16,0x5f,0xde, - 0x3a,0x7d,0x3a,0x1b,0x25,0x89,0x42,0x24,0x3c,0xd9,0x55,0xb7,0xe0,0x0d,0x09,0x84, - 0x80,0x0a,0x44,0x0b,0xdb,0xb2,0xce,0xb1,0x7b,0x2b,0x8a,0x9a,0xa6,0x07,0x9c,0x54, - 0x0e,0x38,0xdc,0x92,0xcb,0x1f,0x2a,0x60,0x72,0x61,0x44,0x51,0x83,0x23,0x5a,0xdb - }, + 0x9b223116545a8f37, 0xde5f16ecd89a4c94, 0x244289251b3a7d3a, 0x84090de0b755d93c, + 0xb1ceb2db0b440a80, 0x549c07a69a8a2b7b, 0x602a1fcb92dc380e, 0xdb5a238351446172 + }, { - 0xab,0xbe,0xde,0xa6,0x80,0x05,0x6f,0x52,0x38,0x2a,0xe5,0x48,0xb2,0xe4,0xf3,0xf3, - 0x89,0x41,0xe7,0x1c,0xff,0x8a,0x78,0xdb,0x1f,0xff,0xe1,0x8a,0x1b,0x33,0x61,0x03, - 0x9f,0xe7,0x67,0x02,0xaf,0x69,0x33,0x4b,0x7a,0x1e,0x6c,0x30,0x3b,0x76,0x52,0xf4, - 0x36,0x98,0xfa,0xd1,0x15,0x3b,0xb6,0xc3,0x74,0xb4,0xc7,0xfb,0x98,0x45,0x9c,0xed - }, + 0x526f0580a6debeab, 0xf3f3e4b248e52a38, 0xdb788aff1ce74189, 0x0361331b8ae1ff1f, + 0x4b3369af0267e79f, 0xf452763b306c1e7a, 0xc3b63b15d1fa9836, 0xed9c4598fbc7b474 + }, { - 0x7b,0xcd,0x9e,0xd0,0xef,0xc8,0x89,0xfb,0x30,0x02,0xc6,0xcd,0x63,0x5a,0xfe,0x94, - 0xd8,0xfa,0x6b,0xbb,0xeb,0xab,0x07,0x61,0x20,0x01,0x80,0x21,0x14,0x84,0x66,0x79, - 0x8a,0x1d,0x71,0xef,0xea,0x48,0xb9,0xca,0xef,0xba,0xcd,0x1d,0x7d,0x47,0x6e,0x98, - 0xde,0xa2,0x59,0x4a,0xc0,0x6f,0xd8,0x5d,0x6b,0xca,0xa4,0xcd,0x81,0xf3,0x2d,0x1b - }, + 0xfb89c8efd09ecd7b, 0x94fe5a63cdc60230, 0x6107abebbb6bfad8, 0x7966841421800120, + 0xcab948eaef711d8a, 0x986e477d1dcdbaef, 0x5dd86fc04a59a2de, 0x1b2df381cda4ca6b + }, { - 0x37,0x8e,0xe7,0x67,0xf1,0x16,0x31,0xba,0xd2,0x13,0x80,0xb0,0x04,0x49,0xb1,0x7a, - 0xcd,0xa4,0x3c,0x32,0xbc,0xdf,0x1d,0x77,0xf8,0x20,0x12,0xd4,0x30,0x21,0x9f,0x9b, - 0x5d,0x80,0xef,0x9d,0x18,0x91,0xcc,0x86,0xe7,0x1d,0xa4,0xaa,0x88,0xe1,0x28,0x52, - 0xfa,0xf4,0x17,0xd5,0xd9,0xb2,0x1b,0x99,0x48,0xbc,0x92,0x4a,0xf1,0x1b,0xd7,0x20 + 0xba3116f167e78e37, 0x7ab14904b08013d2, 0x771ddfbc323ca4cd, 0x9b9f2130d41220f8, + 0x86cc91189def805d, 0x5228e188aaa41de7, 0x991bb2d9d517f4fa, 0x20d71bf14a92bc48 } }; + union GOST3411Block // 8 bytes aligned { @@ -307,15 +781,15 @@ namespace crypto ret.ll[i] = ll[i]^other.ll[i]; return ret; } - - GOST3411Block operator^(const uint8_t * other) const + + GOST3411Block operator^(const uint64_t * other) const { GOST3411Block ret; - for (int i = 0; i < 64; i++) - ret.buf[i] = buf[i]^other[i]; + for (int i = 0; i < 8; i++) + ret.ll[i] = ll[i]^other[i]; return ret; } - + GOST3411Block operator+(const GOST3411Block& other) const { GOST3411Block ret; @@ -340,26 +814,24 @@ namespace crypto } } - void SPL () + void F () { - uint8_t p[64]; - memcpy (p, buf, 64); // we need to copy it for P's transposition - for (int i = 0; i < 8; i++) + uint64_t res[8]; + for (int b=0; b<8; b++) { - uint64_t c = 0; - for (int j = 0; j < 8; j++) - { - uint8_t bit = 0x80; - uint8_t byte = sbox_[p[j*8+i]]; // S - sbox_, P - transpose (i,j) - for (int k = 0; k < 8; k++) - { - if (byte & bit) c ^= A_[j*8+k]; - bit >>= 1; - } - } - ll[i] = htobe64 (c); - } - } + uint64_t r; + r = T0[buf[b+56]]; + r ^= T1[buf[b+48]]; + r ^= T2[buf[b+40]]; + r ^= T3[buf[b+32]]; + r ^= T4[buf[b+24]]; + r ^= T5[buf[b+16]]; + r ^= T6[buf[b+8]]; + r ^= T7[buf[b]]; + res[b] = r; + } + memcpy (buf, res, 64); + } GOST3411Block E (const GOST3411Block& m) { @@ -367,9 +839,9 @@ namespace crypto GOST3411Block res = k^m; for (int i = 0; i < 12; i++) { - res.SPL (); + res.F (); k = k^C_[i]; - k.SPL (); + k.F (); res = k^res; } return res; @@ -379,7 +851,7 @@ namespace crypto static GOST3411Block gN (const GOST3411Block& N, const GOST3411Block& h, const GOST3411Block& m) { GOST3411Block res = N ^ h; - res.SPL (); + res.F (); res = res.E (m); res = res^h; res = res^m; From b14d1801f04ea022cf012f12f76783da5d6025b0 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Fri, 27 Oct 2017 08:42:54 -0400 Subject: [PATCH 71/81] support i2p outproxy --- libi2pd/Destination.cpp | 1 + libi2pd_client/ClientContext.cpp | 6 ++++-- libi2pd_client/HTTPProxy.cpp | 33 +++++++++++++++++++++----------- libi2pd_client/HTTPProxy.h | 10 ++++++++-- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index d6d92388..520fc23f 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "Crypto.h" #include "Log.h" #include "FS.h" diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index e84bcb5f..a15bbb14 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -54,6 +54,7 @@ namespace client std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr); uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); + std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort); if (httpProxyKeys.length () > 0) { @@ -70,7 +71,7 @@ namespace client } try { - m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, localDestination); + m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, httpOutProxyURL, localDestination); m_HttpProxy->Start(); } catch (std::exception& e) @@ -536,7 +537,8 @@ namespace client else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY) { // http proxy - clientTunnel = new i2p::proxy::HTTPProxy(address, port, localDestination); + std::string outproxy = section.second.get("outproxy", ""); + clientTunnel = new i2p::proxy::HTTPProxy(address, port, outproxy, localDestination); clientEndpoint = ((i2p::proxy::HTTPProxy*)clientTunnel)->GetLocalEndpoint (); } else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 526e779e..b1e1a545 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -86,6 +86,7 @@ namespace proxy { std::shared_ptr m_sock; std::shared_ptr m_proxysock; boost::asio::ip::tcp::resolver m_proxy_resolver; + std::string m_OutproxyUrl; i2p::http::URL m_ProxyURL; i2p::http::URL m_RequestURL; uint8_t m_socks_buf[255+8]; // for socks request/response @@ -99,7 +100,8 @@ namespace proxy { HTTPReqHandler(HTTPProxy * parent, std::shared_ptr sock) : I2PServiceHandler(parent), m_sock(sock), m_proxysock(std::make_shared(parent->GetService())), - m_proxy_resolver(parent->GetService()) {} + m_proxy_resolver(parent->GetService()), + m_OutproxyUrl(parent->GetOutproxyURL()) {} ~HTTPReqHandler() { Terminate(); } void Handle () { AsyncSockRead(); } /* overload */ }; @@ -324,10 +326,9 @@ namespace proxy { return true; /* request processed */ } } else { - std::string outproxyUrl; i2p::config::GetOption("httpproxy.outproxy", outproxyUrl); - if(outproxyUrl.size()) { - LogPrint (eLogDebug, "HTTPProxy: use outproxy ", outproxyUrl); - if(m_ProxyURL.parse(outproxyUrl)) + if(m_OutproxyUrl.size()) { + LogPrint (eLogDebug, "HTTPProxy: use outproxy ", m_OutproxyUrl); + if(m_ProxyURL.parse(m_OutproxyUrl)) ForwardToUpstreamProxy(); else GenericProxyError("Outproxy failure", "bad outproxy settings"); @@ -379,10 +380,19 @@ namespace proxy { if (m_ProxyURL.schema == "" || m_ProxyURL.schema == "http") { // handle upstream http proxy if (!m_ProxyURL.port) m_ProxyURL.port = 80; - boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port)); - m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { - m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamHTTPProxyConnect, this, std::placeholders::_1)); - })); + if (m_ProxyURL.is_i2p()) + { + m_send_buf = m_recv_buf; + GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleStreamRequestComplete, + shared_from_this(), std::placeholders::_1), m_ProxyURL.host, m_ProxyURL.port); + } + else + { + boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port)); + m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { + m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamHTTPProxyConnect, this, std::placeholders::_1)); + })); + } } else if (m_ProxyURL.schema == "socks") { // handle upstream socks proxy if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified @@ -572,8 +582,9 @@ namespace proxy { Done (shared_from_this()); } - HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination): - TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) + HTTPProxy::HTTPProxy(const std::string& address, int port, const std::string & outproxy, std::shared_ptr localDestination): + TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), + m_OutproxyUrl(outproxy) { } diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 29b997eb..0adb2d2e 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -6,14 +6,20 @@ namespace proxy { class HTTPProxy: public i2p::client::TCPIPAcceptor { public: - - HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination = nullptr); + HTTPProxy(const std::string& address, int port, const std::string & outproxy, std::shared_ptr localDestination); + HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination = nullptr) : + HTTPProxy(address, port, "", localDestination) {} ; ~HTTPProxy() {}; + std::string GetOutproxyURL() const { return m_OutproxyUrl; } + protected: // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); const char* GetName() { return "HTTP Proxy"; } + + private: + std::string m_OutproxyUrl; }; } // http } // i2p From 1500e805ddcf57950443c0b798161b4eb98957b5 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 5 Feb 2017 10:09:43 -0500 Subject: [PATCH 72/81] add is_i2p --- libi2pd/HTTP.cpp | 7 ++++++- libi2pd/HTTP.h | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp index cc6e724b..c81b1a07 100644 --- a/libi2pd/HTTP.cpp +++ b/libi2pd/HTTP.cpp @@ -29,7 +29,7 @@ namespace http { inline bool is_http_method(const std::string & str) { return std::find(HTTP_METHODS.begin(), HTTP_METHODS.end(), str) != std::end(HTTP_METHODS); } - + void strsplit(const std::string & line, std::vector &tokens, char delim, std::size_t limit = 0) { std::size_t count = 0; std::stringstream ss(line); @@ -195,6 +195,11 @@ namespace http { return out; } + bool URL::is_i2p() const + { + return host.rfind(".i2p") == ( host.size() - 4 ); + } + void HTTPMsg::add_header(const char *name, std::string & value, bool replace) { add_header(name, value.c_str(), replace); } diff --git a/libi2pd/HTTP.h b/libi2pd/HTTP.h index 198362f5..272f2f44 100644 --- a/libi2pd/HTTP.h +++ b/libi2pd/HTTP.h @@ -56,6 +56,11 @@ namespace http * @note Returns relative url if schema if empty, absolute url otherwise */ std::string to_string (); + + /** + * @brief return true if the host is inside i2p + */ + bool is_i2p() const; }; struct HTTPMsg @@ -89,7 +94,7 @@ namespace http /** @brief Serialize HTTP request to string */ std::string to_string(); - void write(std::ostream & o); + void write(std::ostream & o); void AddHeader (const std::string& name, const std::string& value); void UpdateHeader (const std::string& name, const std::string& value); @@ -131,7 +136,7 @@ namespace http std::string to_string(); void write(std::ostream & o); - + /** @brief Checks that response declared as chunked data */ bool is_chunked() const ; From 6441c9d5d82985f5d3a5569938e170c96ded1f3d Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 30 Oct 2017 08:27:55 -0400 Subject: [PATCH 73/81] initial ntcp soft/hard limits --- libi2pd/Config.cpp | 2 ++ libi2pd/NTCPSession.cpp | 18 +++++++++++++++++- libi2pd/NTCPSession.h | 13 +++++++++++++ libi2pd/Transports.cpp | 40 +++++++++++++++++++++++++++------------- 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 26f09696..4997852a 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -71,6 +71,8 @@ namespace config { ("limits.coresize", value()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)") ("limits.openfiles", value()->default_value(0), "Maximum number of open files (0 - use system default)") ("limits.transittunnels", value()->default_value(2500), "Maximum active transit sessions (default:2500)") + ("limits.ntcpsoft", value()->default_value(0), "Threshold to start probabalistic backoff with ntcp sessions (default: use system limit)") + ("limits.ntcphard", value()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)") ; options_description httpserver("HTTP Server options"); diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index a6329f04..cc46f9e6 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -791,7 +791,8 @@ namespace transport NTCPServer::NTCPServer (): m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr), - m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr) + m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr), + m_SoftLimit(0), m_HardLimit(0) { } @@ -965,6 +966,13 @@ namespace transport auto ep = conn->GetSocket ().remote_endpoint(ec); if (!ec) { + if(ShouldLimit()) + { + // hit limit, close premature + LogPrint(eLogWarning, "NTCP: limiting with backoff session from ", ep); + conn->GetSocket().close(); + return; + } LogPrint (eLogDebug, "NTCP: Connected from ", ep); if (conn) { @@ -993,6 +1001,14 @@ namespace transport auto ep = conn->GetSocket ().remote_endpoint(ec); if (!ec) { + if(ShouldLimit()) + { + // hit limit, close premature + LogPrint(eLogWarning, "NTCP: limiting with backoff on session from ", ep); + conn->GetSocket().close(); + return; + } + LogPrint (eLogDebug, "NTCP: Connected from ", ep); if (conn) { diff --git a/libi2pd/NTCPSession.h b/libi2pd/NTCPSession.h index a45f06f7..b64f63aa 100644 --- a/libi2pd/NTCPSession.h +++ b/libi2pd/NTCPSession.h @@ -167,8 +167,19 @@ namespace transport boost::asio::io_service& GetService () { return m_Service; }; + void SetSessionLimits(uint16_t softLimit, uint16_t hardLimit) { m_SoftLimit = softLimit; m_HardLimit = hardLimit; } + bool ShouldLimit() const { return ShouldHardLimit() || ShouldSoftLimit(); } private: + /** @brief return true for hard limit */ + bool ShouldHardLimit() const { return m_HardLimit && m_NTCPSessions.size() >= m_HardLimit; } + + /** @brief return true for probabalistic soft backoff */ + bool ShouldSoftLimit() const + { + auto sessions = m_NTCPSessions.size(); + return sessions && m_SoftLimit && m_SoftLimit < sessions && ( rand() % sessions ) <= m_SoftLimit; + } void Run (); void HandleAccept (std::shared_ptr conn, const boost::system::error_code& error); void HandleAcceptV6 (std::shared_ptr conn, const boost::system::error_code& error); @@ -198,6 +209,8 @@ namespace transport uint16_t m_ProxyPort; boost::asio::ip::tcp::resolver m_Resolver; boost::asio::ip::tcp::endpoint * m_ProxyEndpoint; + + uint16_t m_SoftLimit, m_HardLimit; public: // for HTTP/I2PControl diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index f375296f..3ae0d56a 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -147,13 +147,20 @@ namespace transport m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service); } - i2p::config::GetOption("nat", m_IsNAT); - + i2p::config::GetOption("nat", m_IsNAT); m_DHKeysPairSupplier.Start (); m_IsRunning = true; m_Thread = new std::thread (std::bind (&Transports::Run, this)); std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy); i2p::http::URL proxyurl; + uint16_t softLimit, hardLimit; + i2p::config::GetOption("limits.ntcpsoft", softLimit); + i2p::config::GetOption("limits.ntcphard", hardLimit); + if(softLimit >= hardLimit) + { + LogPrint(eLogError, "ntcp soft limit must be less than ntcp hard limit"); + return; + } if(ntcpproxy.size() && enableNTCP) { if(proxyurl.parse(ntcpproxy)) @@ -161,12 +168,11 @@ namespace transport if(proxyurl.schema == "socks" || proxyurl.schema == "http") { m_NTCPServer = new NTCPServer(); - + m_NTCPServer->SetSessionLimits(softLimit, hardLimit); NTCPServer::ProxyType proxytype = NTCPServer::eSocksProxy; if (proxyurl.schema == "http") proxytype = NTCPServer::eHTTPProxy; - m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; m_NTCPServer->Start(); if(!m_NTCPServer->NetworkIsReady()) @@ -193,6 +199,7 @@ namespace transport if (m_NTCPServer == nullptr && enableNTCP) { m_NTCPServer = new NTCPServer (); + m_NTCPServer->SetSessionLimits(softLimit, hardLimit); m_NTCPServer->Start (); if (!(m_NTCPServer->IsBoundV6() || m_NTCPServer->IsBoundV4())) { /** failed to bind to NTCP */ @@ -394,20 +401,27 @@ namespace transport { if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ()) { - auto s = std::make_shared (*m_NTCPServer, peer.router); - if(m_NTCPServer->UsingProxy()) + if(!m_NTCPServer->ShouldLimit()) { - NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address; - std::string addr = address->host.to_string(); + auto s = std::make_shared (*m_NTCPServer, peer.router); + if(m_NTCPServer->UsingProxy()) + { + NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address; + std::string addr = address->host.to_string(); - if(address->host.is_v6()) - remote = NTCPServer::eIP6Address; + if(address->host.is_v6()) + remote = NTCPServer::eIP6Address; - m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s); + m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s); + } + else + m_NTCPServer->Connect (address->host, address->port, s); + return true; } else - m_NTCPServer->Connect (address->host, address->port, s); - return true; + { + LogPrint(eLogWarning, "Transports: NTCP Limit hit falling back to SSU"); + } } } else // we don't have address From 7a9dc0eec0998b8623595c398c9a1ed78f924012 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 30 Oct 2017 08:37:54 -0400 Subject: [PATCH 74/81] use terminate --- libi2pd/NTCPSession.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/NTCPSession.cpp b/libi2pd/NTCPSession.cpp index cc46f9e6..27f30600 100644 --- a/libi2pd/NTCPSession.cpp +++ b/libi2pd/NTCPSession.cpp @@ -970,7 +970,7 @@ namespace transport { // hit limit, close premature LogPrint(eLogWarning, "NTCP: limiting with backoff session from ", ep); - conn->GetSocket().close(); + conn->Terminate(); return; } LogPrint (eLogDebug, "NTCP: Connected from ", ep); @@ -1005,7 +1005,7 @@ namespace transport { // hit limit, close premature LogPrint(eLogWarning, "NTCP: limiting with backoff on session from ", ep); - conn->GetSocket().close(); + conn->Terminate(); return; } From 91eb2b2c4abdedd261b62765734cea0c770e634b Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 30 Oct 2017 09:53:41 -0400 Subject: [PATCH 75/81] fix limits when not specififed --- libi2pd/Transports.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 3ae0d56a..bb94036a 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -156,7 +156,7 @@ namespace transport uint16_t softLimit, hardLimit; i2p::config::GetOption("limits.ntcpsoft", softLimit); i2p::config::GetOption("limits.ntcphard", hardLimit); - if(softLimit >= hardLimit) + if(softLimit > 0 && hardLimit > 0 && softLimit >= hardLimit) { LogPrint(eLogError, "ntcp soft limit must be less than ntcp hard limit"); return; From 63ae6850d3db952e948c17eee2269eed2964111f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Oct 2017 12:58:20 -0400 Subject: [PATCH 76/81] Fix #979. Router without host but with introducers is considered as SSU v4 --- libi2pd/RouterInfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index be2a5904..3719e68a 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -166,7 +166,6 @@ namespace data for (int i = 0; i < numAddresses; i++) { uint8_t supportedTransports = 0; - bool isValidAddress = true; auto address = std::make_shared
(); s.read ((char *)&address->cost, sizeof (address->cost)); s.read ((char *)&address->date, sizeof (address->date)); @@ -269,7 +268,8 @@ namespace data } if (!s) return; } - if (isValidAddress) + if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented + if (supportedTransports) { addresses->push_back(address); m_SupportedTransports |= supportedTransports; From 39c1c3567b3876e1bdfefa516f0ed11c4b29662f Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 Oct 2017 16:16:21 -0400 Subject: [PATCH 77/81] ECICSEncrypt added --- libi2pd/Crypto.cpp | 36 ++++++++++++++++++++++++++++++++++++ libi2pd/Crypto.h | 4 ++++ 2 files changed, 40 insertions(+) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 0ac65671..329bd5ea 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -372,6 +372,42 @@ namespace crypto BN_CTX_free (ctx); } +// ECICS + void ECICSEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) + { + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order(curve, q, ctx); + int len = BN_num_bytes (q); + BIGNUM * k = BN_CTX_get (ctx); + BN_rand_range (k, q); // 0 < k < q + // point for shared secret + auto p = EC_POINT_new (curve); + EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx); + BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); + EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); + bn2buf (x, encrypted, len); + bn2buf (y, encrypted + len, len); + RAND_bytes (encrypted + 2*len, 256 - 2*len); + // ecryption key + EC_POINT_mul (curve, p, nullptr, key, k, ctx); + EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); + uint8_t keyBuf[64], shared[32]; + bn2buf (x, keyBuf, len); + SHA256 (keyBuf, len, shared); + // create buffer + uint8_t m[256]; + m[0] = 0xFF; m[255] = 0xFF; + memcpy (m+33, data, 222); + SHA256 (m+33, 222, m+1); + // encrypt + AES_KEY aesKey; + AES_set_encrypt_key (shared, 256, &aesKey); + AES_encrypt (m, encrypted + 256, &aesKey); + EC_POINT_free (p); + BN_CTX_end (ctx); + } + // HMAC const uint64_t IPAD = 0x3636363636363636; const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index cb0152ba..a683f46b 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -52,6 +52,10 @@ namespace crypto bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); + // ECICS + void ECICSEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 512 bytes encrypted + + // HMAC typedef i2p::data::Tag<32> MACKey; void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest); From 12feac1f50ff6f6be1df0d621e5d6a06ba84aea8 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 Oct 2017 21:25:52 -0400 Subject: [PATCH 78/81] fixed build error for wheezy --- libi2pd/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libi2pd/util.h b/libi2pd/util.h index 5297b3ed..813af0fb 100644 --- a/libi2pd/util.h +++ b/libi2pd/util.h @@ -33,7 +33,7 @@ namespace util template class MemoryPool { - BOOST_STATIC_ASSERT_MSG(sizeof(T) >= sizeof(void*), "size cannot be less that general pointer size"); + //BOOST_STATIC_ASSERT_MSG(sizeof(T) >= sizeof(void*), "size cannot be less that general pointer size"); public: From 6d017269616c6b295a0a17bc58bc32640af12565 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Nov 2017 10:20:11 -0400 Subject: [PATCH 79/81] use AES-CBC for ECICS --- libi2pd/Crypto.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 329bd5ea..eaa4b17e 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -389,11 +389,12 @@ namespace crypto bn2buf (x, encrypted, len); bn2buf (y, encrypted + len, len); RAND_bytes (encrypted + 2*len, 256 - 2*len); - // ecryption key + // ecryption key and iv EC_POINT_mul (curve, p, nullptr, key, k, ctx); EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr); - uint8_t keyBuf[64], shared[32]; + uint8_t keyBuf[64], iv[64], shared[32]; bn2buf (x, keyBuf, len); + bn2buf (y, iv, len); SHA256 (keyBuf, len, shared); // create buffer uint8_t m[256]; @@ -401,9 +402,10 @@ namespace crypto memcpy (m+33, data, 222); SHA256 (m+33, 222, m+1); // encrypt - AES_KEY aesKey; - AES_set_encrypt_key (shared, 256, &aesKey); - AES_encrypt (m, encrypted + 256, &aesKey); + CBCEncryption encryption; + encryption.SetKey (shared); + encryption.SetIV (iv); + encryption.Encrypt (m, 256, encrypted + 256); EC_POINT_free (p); BN_CTX_end (ctx); } From 5271cdacf2d50108cea30f6819815ac14989861f Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Nov 2017 10:59:36 -0400 Subject: [PATCH 80/81] ECICSDecrypt --- libi2pd/Crypto.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++ libi2pd/Crypto.h | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index eaa4b17e..8eff7b8a 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -410,6 +410,56 @@ namespace crypto BN_CTX_end (ctx); } + bool ECICSDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx) + { + bool ret = true; + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order(curve, q, ctx); + int len = BN_num_bytes (q); + // point for shared secret + BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx); + BN_bin2bn (encrypted, len, x); + BN_bin2bn (encrypted + len, len, y); + auto p = EC_POINT_new (curve); + if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr)) + { + auto s = EC_POINT_new (curve); + EC_POINT_mul (curve, s, nullptr, p, key, ctx); + EC_POINT_get_affine_coordinates_GFp (curve, s, x, y, nullptr); + EC_POINT_free (s); + uint8_t keyBuf[64], iv[64], shared[32]; + bn2buf (x, keyBuf, len); + bn2buf (y, iv, len); + SHA256 (keyBuf, len, shared); + // decrypt + uint8_t m[256]; + CBCDecryption decryption; + decryption.SetKey (shared); + decryption.SetIV (iv); + decryption.Decrypt (encrypted + 256, 256, m); + // verify and copy + uint8_t hash[32]; + SHA256 (m + 33, 222, hash); + if (!memcmp (m + 1, hash, 32)) + memcpy (data, m + 33, 222); + else + { + LogPrint (eLogError, "ECICS decrypt hash doesn't match"); + ret = false; + } + } + else + { + LogPrint (eLogError, "ECICS decrypt point is invalid"); + ret = false; + } + + EC_POINT_free (p); + BN_CTX_end (ctx); + return ret; + } + // HMAC const uint64_t IPAD = 0x3636363636363636; const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index a683f46b..ff9467e9 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -54,7 +54,7 @@ namespace crypto // ECICS void ECICSEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 512 bytes encrypted - + bool ECICSDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); // HMAC typedef i2p::data::Tag<32> MACKey; From 00bbb813759d04546250b72e520f664186bccaea Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Nov 2017 14:06:55 -0400 Subject: [PATCH 81/81] ECICS gerenarate keys --- libi2pd/Crypto.cpp | 13 +++++++++++++ libi2pd/Crypto.h | 1 + 2 files changed, 14 insertions(+) diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 8eff7b8a..caae5d82 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -460,6 +460,19 @@ namespace crypto return ret; } + void GenerateECICSKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub) + { + BN_CTX * ctx = BN_CTX_new (); + BIGNUM * q = BN_new (); + EC_GROUP_get_order(curve, q, ctx); + priv = BN_new (); + BN_rand_range (priv, q); + pub = EC_POINT_new (curve); + EC_POINT_mul (curve, pub, priv, nullptr, nullptr, ctx); + BN_free (q); + BN_CTX_free (ctx); + } + // HMAC const uint64_t IPAD = 0x3636363636363636; const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index ff9467e9..18948490 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -55,6 +55,7 @@ namespace crypto // ECICS void ECICSEncrypt (const EC_GROUP * curve, const EC_POINT * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx); // 222 bytes data, 512 bytes encrypted bool ECICSDecrypt (const EC_GROUP * curve, const BIGNUM * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx); + void GenerateECICSKeyPair (const EC_GROUP * curve, BIGNUM *& priv, EC_POINT *& pub); // HMAC typedef i2p::data::Tag<32> MACKey;