mainwindow.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QObject>
  4. #include <QMainWindow>
  5. #include <QPushButton>
  6. #include <QtCore/QVariant>
  7. #include <QtWidgets/QAction>
  8. #include <QtWidgets/QApplication>
  9. #include <QtWidgets/QButtonGroup>
  10. #include <QtWidgets/QHeaderView>
  11. #include <QtWidgets/QMainWindow>
  12. #include <QtWidgets/QVBoxLayout>
  13. #include <QtWidgets/QWidget>
  14. #include <QtWidgets/QCheckBox>
  15. #include <QtWidgets/QComboBox>
  16. #include <QtWidgets/QAction>
  17. #include <QtWidgets/QGridLayout>
  18. #include <QtWidgets/QGroupBox>
  19. #include <QtWidgets/QHBoxLayout>
  20. #include <QtWidgets/QHeaderView>
  21. #include <QtWidgets/QLabel>
  22. #include <QtWidgets/QLineEdit>
  23. #include <QtWidgets/QPushButton>
  24. #include <QtWidgets/QSpacerItem>
  25. #include "QVBoxLayout"
  26. #include "QUrl"
  27. #ifndef ANDROID
  28. # include <QSystemTrayIcon>
  29. # include <QCloseEvent>
  30. # include <QMenu>
  31. #endif
  32. #include <QString>
  33. #include <functional>
  34. #include "MainWindowItems.h"
  35. #include "TunnelPane.h"
  36. #include "ServerTunnelPane.h"
  37. #include "ClientTunnelPane.h"
  38. #include "TunnelConfig.h"
  39. #include "textbrowsertweaked1.h"
  40. #include "Config.h"
  41. #include "FS.h"
  42. #include <QDebug>
  43. #include <boost/property_tree/ptree.hpp>
  44. #include <boost/property_tree/ini_parser.hpp>
  45. #include "TunnelsPageUpdateListener.h"
  46. #include "DaemonQT.h"
  47. #include "SignatureTypeComboboxFactory.h"
  48. #include "pagewithbackbutton.h"
  49. #include <iostream>
  50. #include "widgetlockregistry.h"
  51. #include "widgetlock.h"
  52. class LogViewerManager;
  53. template<typename ValueType>
  54. bool isType(boost::any& a) {
  55. return
  56. #ifdef BOOST_AUX_ANY_TYPE_ID_NAME
  57. std::strcmp(a.type().name(), typeid(ValueType).name()) == 0
  58. #else
  59. a.type() == typeid(ValueType)
  60. #endif
  61. ;
  62. }
  63. class ConfigOption {
  64. public:
  65. QString section;
  66. QString option;
  67. //MainWindow::DefaultValueGetter defaultValueGetter;
  68. ConfigOption(QString section_, QString option_/*, DefaultValueGetter defaultValueGetter_*/):
  69. section(section_)
  70. , option(option_)
  71. //, defaultValueGetter(defaultValueGetter_)
  72. {}
  73. };
  74. extern std::string programOptionsWriterCurrentSection;
  75. class MainWindow;
  76. class MainWindowItem : public QObject {
  77. Q_OBJECT
  78. ConfigOption option;
  79. QWidget* widgetToFocus;
  80. QString requirementToBeValid;
  81. public:
  82. MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_) : option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_) {}
  83. QWidget* getWidgetToFocus(){return widgetToFocus;}
  84. QString& getRequirementToBeValid() { return requirementToBeValid; }
  85. ConfigOption& getConfigOption() { return option; }
  86. boost::any optionValue;
  87. virtual ~MainWindowItem(){}
  88. virtual void installListeners(MainWindow *mainWindow);
  89. virtual void loadFromConfigOption(){
  90. std::string optName="";
  91. if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
  92. optName+=option.option.toStdString();
  93. //qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
  94. boost::any programOption;
  95. i2p::config::GetOptionAsAny(optName, programOption);
  96. optionValue=programOption.empty()?boost::any(std::string(""))
  97. :boost::any_cast<boost::program_options::variable_value>(programOption).value();
  98. }
  99. virtual void saveToStringStream(std::stringstream& out){
  100. if(isType<std::string>(optionValue)) {
  101. std::string v = boost::any_cast<std::string>(optionValue);
  102. if(v.empty())return;
  103. }
  104. if(optionValue.empty())return;
  105. std::string rtti = optionValue.type().name();
  106. std::string optName="";
  107. if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
  108. optName+=option.option.toStdString();
  109. qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str();
  110. std::string sectionAsStdStr = option.section.toStdString();
  111. if(!option.section.isEmpty() &&
  112. sectionAsStdStr!=programOptionsWriterCurrentSection) {
  113. out << "[" << sectionAsStdStr << "]\n";
  114. programOptionsWriterCurrentSection=sectionAsStdStr;
  115. }
  116. out << option.option.toStdString() << "=";
  117. if(isType<std::string>(optionValue)) {
  118. out << boost::any_cast<std::string>(optionValue);
  119. }else if(isType<bool>(optionValue)) {
  120. out << (boost::any_cast<bool>(optionValue) ? "true" : "false");
  121. }else if(isType<uint16_t>(optionValue)) {
  122. out << boost::any_cast<uint16_t>(optionValue);
  123. }else if(isType<uint32_t>(optionValue)) {
  124. out << boost::any_cast<uint32_t>(optionValue);
  125. }else if(isType<int>(optionValue)) {
  126. out << boost::any_cast<int>(optionValue);
  127. }else if(isType<unsigned short>(optionValue)) {
  128. out << boost::any_cast<unsigned short>(optionValue);
  129. }else out << boost::any_cast<std::string>(optionValue); //let it throw
  130. out << "\n\n";
  131. }
  132. virtual bool isValid(){return true;}
  133. };
  134. class NonGUIOptionItem : public MainWindowItem {
  135. public:
  136. NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {};
  137. virtual ~NonGUIOptionItem(){}
  138. virtual bool isValid() { return true; }
  139. };
  140. class BaseStringItem : public MainWindowItem {
  141. Q_OBJECT
  142. public:
  143. QLineEdit* lineEdit;
  144. BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_) : MainWindowItem(option_, lineEdit_, requirementToBeValid_), lineEdit(lineEdit_){};
  145. virtual ~BaseStringItem(){}
  146. virtual void installListeners(MainWindow *mainWindow);
  147. virtual QString toString(){
  148. return boost::any_cast<std::string>(optionValue).c_str();
  149. }
  150. virtual boost::any fromString(QString s){return boost::any(s.toStdString());}
  151. virtual void loadFromConfigOption(){
  152. MainWindowItem::loadFromConfigOption();
  153. lineEdit->setText(toString());
  154. }
  155. virtual void saveToStringStream(std::stringstream& out){
  156. optionValue=fromString(lineEdit->text());
  157. MainWindowItem::saveToStringStream(out);
  158. }
  159. virtual bool isValid() { return true; }
  160. };
  161. class FileOrFolderChooserItem : public BaseStringItem {
  162. public:
  163. QPushButton* browsePushButton;
  164. FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
  165. BaseStringItem(option_, lineEdit_, QString()), browsePushButton(browsePushButton_) {}
  166. virtual ~FileOrFolderChooserItem(){}
  167. };
  168. class FileChooserItem : public FileOrFolderChooserItem {
  169. Q_OBJECT
  170. private slots:
  171. void pushButtonReleased();
  172. public:
  173. FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
  174. FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) {
  175. QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
  176. }
  177. };
  178. class FolderChooserItem : public FileOrFolderChooserItem{
  179. Q_OBJECT
  180. private slots:
  181. void pushButtonReleased();
  182. public:
  183. FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_) :
  184. FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_) {
  185. QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
  186. }
  187. };
  188. class ComboBoxItem : public MainWindowItem {
  189. public:
  190. QComboBox* comboBox;
  191. ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){};
  192. virtual ~ComboBoxItem(){}
  193. virtual void installListeners(MainWindow *mainWindow);
  194. virtual void loadFromConfigOption()=0;
  195. virtual void saveToStringStream(std::stringstream& out)=0;
  196. virtual bool isValid() { return true; }
  197. };
  198. class LogDestinationComboBoxItem : public ComboBoxItem {
  199. public:
  200. LogDestinationComboBoxItem(ConfigOption option_, QComboBox* comboBox_) :
  201. ComboBoxItem(option_, comboBox_) {}
  202. virtual ~LogDestinationComboBoxItem(){}
  203. virtual void loadFromConfigOption(){
  204. MainWindowItem::loadFromConfigOption();
  205. const char * ld = boost::any_cast<std::string>(optionValue).c_str();
  206. comboBox->setCurrentText(QString(ld));
  207. }
  208. virtual void saveToStringStream(std::stringstream& out){
  209. std::string logDest = comboBox->currentText().toStdString();
  210. optionValue=logDest;
  211. MainWindowItem::saveToStringStream(out);
  212. }
  213. virtual bool isValid() { return true; }
  214. Q_OBJECT
  215. };
  216. class LogLevelComboBoxItem : public ComboBoxItem {
  217. public:
  218. LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {};
  219. virtual ~LogLevelComboBoxItem(){}
  220. virtual void loadFromConfigOption(){
  221. MainWindowItem::loadFromConfigOption();
  222. const char * ll = boost::any_cast<std::string>(optionValue).c_str();
  223. comboBox->setCurrentText(QString(ll));
  224. }
  225. virtual void saveToStringStream(std::stringstream& out){
  226. optionValue=comboBox->currentText().toStdString();
  227. MainWindowItem::saveToStringStream(out);
  228. }
  229. virtual bool isValid() { return true; }
  230. };
  231. class SignatureTypeComboBoxItem : public ComboBoxItem {
  232. public:
  233. SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {};
  234. virtual ~SignatureTypeComboBoxItem(){}
  235. virtual void loadFromConfigOption(){
  236. MainWindowItem::loadFromConfigOption();
  237. while(comboBox->count()>0)comboBox->removeItem(0);
  238. uint16_t selected = (uint16_t) boost::any_cast<unsigned short>(optionValue);
  239. SignatureTypeComboBoxFactory::fillComboBox(comboBox, selected);
  240. }
  241. virtual void saveToStringStream(std::stringstream& out){
  242. uint16_t selected = SignatureTypeComboBoxFactory::getSigType(comboBox->currentData());
  243. optionValue=(unsigned short)selected;
  244. MainWindowItem::saveToStringStream(out);
  245. }
  246. virtual bool isValid() { return true; }
  247. };
  248. class CheckBoxItem : public MainWindowItem {
  249. public:
  250. QCheckBox* checkBox;
  251. CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){};
  252. virtual ~CheckBoxItem(){}
  253. virtual void installListeners(MainWindow *mainWindow);
  254. virtual void loadFromConfigOption(){
  255. MainWindowItem::loadFromConfigOption();
  256. checkBox->setChecked(boost::any_cast<bool>(optionValue));
  257. }
  258. virtual void saveToStringStream(std::stringstream& out){
  259. optionValue=checkBox->isChecked();
  260. MainWindowItem::saveToStringStream(out);
  261. }
  262. virtual bool isValid() { return true; }
  263. };
  264. class BaseFormattedStringItem : public BaseStringItem {
  265. public:
  266. QString fieldNameTranslated;
  267. BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_) :
  268. BaseStringItem(option_, lineEdit_, requirementToBeValid_), fieldNameTranslated(fieldNameTranslated_) {};
  269. virtual ~BaseFormattedStringItem(){}
  270. virtual bool isValid()=0;
  271. };
  272. class IntegerStringItem : public BaseFormattedStringItem {
  273. public:
  274. IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
  275. BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer.")) {};
  276. virtual ~IntegerStringItem(){}
  277. virtual bool isValid(){
  278. auto str=lineEdit->text();
  279. bool ok;
  280. str.toInt(&ok);
  281. return ok;
  282. }
  283. virtual QString toString(){return QString::number(boost::any_cast<int>(optionValue));}
  284. virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));}
  285. };
  286. class UShortStringItem : public BaseFormattedStringItem {
  287. public:
  288. UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
  289. BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer.")) {};
  290. virtual ~UShortStringItem(){}
  291. virtual bool isValid(){
  292. auto str=lineEdit->text();
  293. bool ok;
  294. str.toUShort(&ok);
  295. return ok;
  296. }
  297. virtual QString toString(){return QString::number(boost::any_cast<unsigned short>(optionValue));}
  298. virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));}
  299. };
  300. class UInt32StringItem : public BaseFormattedStringItem {
  301. public:
  302. UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
  303. BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer.")) {};
  304. virtual ~UInt32StringItem(){}
  305. virtual bool isValid(){
  306. auto str=lineEdit->text();
  307. bool ok;
  308. str.toUInt(&ok);
  309. return ok;
  310. }
  311. virtual QString toString(){return QString::number(boost::any_cast<uint32_t>(optionValue));}
  312. virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));}
  313. };
  314. class UInt16StringItem : public BaseFormattedStringItem {
  315. public:
  316. UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
  317. BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer.")) {};
  318. virtual ~UInt16StringItem(){}
  319. virtual bool isValid(){
  320. auto str=lineEdit->text();
  321. bool ok;
  322. str.toUShort(&ok);
  323. return ok;
  324. }
  325. virtual QString toString(){return QString::number(boost::any_cast<uint16_t>(optionValue));}
  326. virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));}
  327. };
  328. class IPAddressStringItem : public BaseFormattedStringItem {
  329. public:
  330. IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
  331. BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address")) {};
  332. virtual bool isValid(){return true;}//todo
  333. };
  334. class TCPPortStringItem : public UShortStringItem {
  335. public:
  336. TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_) :
  337. UShortStringItem(option_, lineEdit_, fieldNameTranslated_) {};
  338. };
  339. namespace Ui {
  340. class MainWindow;
  341. class StatusButtonsForm;
  342. class routerCommandsWidget;
  343. class GeneralSettingsContentsForm;
  344. }
  345. using namespace i2p::client;
  346. class TunnelPane;
  347. using namespace i2p::qt;
  348. class Controller;
  349. class MainWindow : public QMainWindow {
  350. Q_OBJECT
  351. private:
  352. std::shared_ptr<std::iostream> logStream;
  353. public:
  354. explicit MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *parent=nullptr);
  355. ~MainWindow();
  356. void setI2PController(i2p::qt::Controller* controller_);
  357. void highlightWrongInput(QString warningText, QWidget* widgetToFocus);
  358. //typedef std::function<QString ()> DefaultValueGetter;
  359. //#ifndef ANDROID
  360. // void setVisible(bool visible);
  361. //#endif
  362. private:
  363. enum StatusPage {main_page, commands, local_destinations, leasesets, tunnels, transit_tunnels,
  364. transports, i2p_tunnels, sam_sessions};
  365. private slots:
  366. void updated();
  367. void handleQuitButton();
  368. void handleGracefulQuitButton();
  369. void handleDoRestartButton();
  370. void handleGracefulQuitTimerEvent();
  371. #ifndef ANDROID
  372. void setIcon();
  373. void iconActivated(QSystemTrayIcon::ActivationReason reason);
  374. void toggleVisibilitySlot();
  375. #endif
  376. void scheduleStatusPageUpdates();
  377. void statusHtmlPageMouseReleased();
  378. void statusHtmlPageSelectionChanged();
  379. void updateStatusPage();
  380. void showStatusMainPage();
  381. void showStatus_commands_Page();
  382. void runPeerTest();
  383. void enableTransit();
  384. void disableTransit();
  385. public slots:
  386. void showStatus_local_destinations_Page();
  387. void showStatus_leasesets_Page();
  388. void showStatus_tunnels_Page();
  389. void showStatus_transit_tunnels_Page();
  390. void showStatus_transports_Page();
  391. void showStatus_i2p_tunnels_Page();
  392. void showStatus_sam_sessions_Page();
  393. void showLogViewerPage();
  394. void showSettingsPage();
  395. void showTunnelsPage();
  396. void showRestartPage();
  397. void showQuitPage();
  398. private:
  399. StatusPage statusPage;
  400. QTimer * statusPageUpdateTimer;
  401. bool wasSelectingAtStatusMainPage;
  402. bool showHiddenInfoStatusMainPage;
  403. LogViewerManager *logViewerManagerPtr;
  404. void showStatusPage(StatusPage newStatusPage);
  405. #ifndef ANDROID
  406. void createActions();
  407. void createTrayIcon();
  408. bool quitting;
  409. QAction *toggleWindowVisibleAction;
  410. QSystemTrayIcon *trayIcon;
  411. QMenu *trayIconMenu;
  412. #endif
  413. public:
  414. Ui::MainWindow* ui;
  415. Ui::StatusButtonsForm* statusButtonsUI;
  416. Ui::routerCommandsWidget* routerCommandsUI;
  417. Ui::GeneralSettingsContentsForm* uiSettings;
  418. void adjustSizesAccordingToWrongLabel();
  419. bool applyTunnelsUiToConfigs();
  420. private:
  421. int settingsTitleLabelNominalHeight;
  422. TextBrowserTweaked1 * textBrowser;
  423. QWidget * routerCommandsParent;
  424. PageWithBackButton * pageWithBackButton;
  425. TextBrowserTweaked1 * childTextBrowser;
  426. widgetlockregistry widgetlocks;
  427. i2p::qt::Controller* i2pController;
  428. protected:
  429. void updateRouterCommandsButtons();
  430. #ifndef ANDROID
  431. void closeEvent(QCloseEvent *event);
  432. #endif
  433. void resizeEvent(QResizeEvent* event);
  434. void onResize();
  435. void setStatusButtonsVisible(bool visible);
  436. QString getStatusPageHtml(bool showHiddenInfo);
  437. QList<MainWindowItem*> configItems;
  438. NonGUIOptionItem* daemonOption;
  439. NonGUIOptionItem* serviceOption;
  440. //LogDestinationComboBoxItem* logOption;
  441. FileChooserItem* logFileNameOption;
  442. FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton);
  443. void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton);
  444. //void initCombobox(ConfigOption option, QComboBox* comboBox);
  445. void initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox);
  446. void initLogLevelCombobox(ConfigOption option, QComboBox* comboBox);
  447. void initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox);
  448. void initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated);
  449. void initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated);
  450. void initCheckBox(ConfigOption option, QCheckBox* checkBox);
  451. void initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
  452. void initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
  453. void initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
  454. void initStringBox(ConfigOption option, QLineEdit* lineEdit);
  455. NonGUIOptionItem* initNonGUIOption(ConfigOption option);
  456. void loadAllConfigs();
  457. public slots:
  458. /** returns false iff not valid items present and save was aborted */
  459. bool saveAllConfigs();
  460. void SaveTunnelsConfig();
  461. void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus);
  462. //focus none
  463. void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); }
  464. void addServerTunnelPushButtonReleased();
  465. void addClientTunnelPushButtonReleased();
  466. void anchorClickedHandler(const QUrl & link);
  467. void backClickedFromChild();
  468. void logDestinationComboBoxValueChanged(const QString & text);
  469. private:
  470. QString datadir;
  471. QString confpath;
  472. QString tunconfpath;
  473. std::map<std::string, TunnelConfig*> tunnelConfigs;
  474. std::list<TunnelPane*> tunnelPanes;
  475. void appendTunnelForms(std::string tunnelNameToFocus);
  476. void deleteTunnelForms();
  477. template<typename Section, typename Type>
  478. std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
  479. {
  480. return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
  481. }
  482. template<typename Section>
  483. void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options, I2CPParameters& param
  484. /*TODO fill param*/) const
  485. {
  486. std::string _INBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
  487. param.setInbound_length(QString(_INBOUND_TUNNEL_LENGTH.c_str()));
  488. std::string _OUTBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
  489. param.setOutbound_length(QString(_OUTBOUND_TUNNEL_LENGTH.c_str()));
  490. std::string _INBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
  491. param.setInbound_quantity( QString(_INBOUND_TUNNELS_QUANTITY.c_str()));
  492. std::string _OUTBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
  493. param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str()));
  494. std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
  495. param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str()));
  496. options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param
  497. options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param
  498. }
  499. void CreateDefaultI2CPOptions (I2CPParameters& param
  500. /*TODO fill param*/) const
  501. {
  502. const int _INBOUND_TUNNEL_LENGTH = DEFAULT_INBOUND_TUNNEL_LENGTH;
  503. param.setInbound_length(QString::number(_INBOUND_TUNNEL_LENGTH));
  504. const int _OUTBOUND_TUNNEL_LENGTH = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
  505. param.setOutbound_length(QString::number(_OUTBOUND_TUNNEL_LENGTH));
  506. const int _INBOUND_TUNNELS_QUANTITY = DEFAULT_INBOUND_TUNNELS_QUANTITY;
  507. param.setInbound_quantity( QString::number(_INBOUND_TUNNELS_QUANTITY));
  508. const int _OUTBOUND_TUNNELS_QUANTITY = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
  509. param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY));
  510. const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND;
  511. param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND));
  512. }
  513. void DeleteTunnelNamed(std::string name) {
  514. std::map<std::string,TunnelConfig*>::const_iterator it=tunnelConfigs.find(name);
  515. if(it!=tunnelConfigs.end()){
  516. TunnelConfig* tc=it->second;
  517. tunnelConfigs.erase(it);
  518. delete tc;
  519. }
  520. saveAllConfigs();
  521. reloadTunnelsConfigAndUI("");
  522. }
  523. std::string GenerateNewTunnelName() {
  524. int i=1;
  525. while(true){
  526. std::stringstream name;
  527. name << "name" << i;
  528. const std::string& str=name.str();
  529. if(tunnelConfigs.find(str)==tunnelConfigs.end())return str;
  530. ++i;
  531. }
  532. }
  533. void CreateDefaultClientTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
  534. std::string name=GenerateNewTunnelName();
  535. std::string type = I2P_TUNNELS_SECTION_TYPE_CLIENT;
  536. std::string dest = "127.0.0.1";
  537. int port = 0;
  538. std::string keys = "";
  539. std::string address = "127.0.0.1";
  540. int destinationPort = 0;
  541. i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
  542. // I2CP
  543. I2CPParameters i2cpParameters;
  544. CreateDefaultI2CPOptions (i2cpParameters);
  545. tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
  546. dest,
  547. port,
  548. keys,
  549. address,
  550. destinationPort,
  551. sigType);
  552. saveAllConfigs();
  553. reloadTunnelsConfigAndUI(name);
  554. }
  555. void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
  556. std::string name=GenerateNewTunnelName();
  557. std::string type=I2P_TUNNELS_SECTION_TYPE_SERVER;
  558. std::string host = "127.0.0.1";
  559. int port = 0;
  560. std::string keys = "";
  561. int inPort = 0;
  562. std::string accessList = "";
  563. std::string hostOverride = "";
  564. std::string webircpass = "";
  565. bool gzip = true;
  566. i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
  567. std::string address = "127.0.0.1";
  568. bool isUniqueLocal = true;
  569. // I2CP
  570. I2CPParameters i2cpParameters;
  571. CreateDefaultI2CPOptions (i2cpParameters);
  572. tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
  573. host,
  574. port,
  575. keys,
  576. inPort,
  577. accessList,
  578. hostOverride,
  579. webircpass,
  580. gzip,
  581. sigType,
  582. address,
  583. isUniqueLocal);
  584. saveAllConfigs();
  585. reloadTunnelsConfigAndUI(name);
  586. }
  587. void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
  588. {
  589. boost::property_tree::ptree pt;
  590. std::string tunConf=tunconfpath.toStdString();
  591. if (tunConf == "") {
  592. // TODO: cleanup this in 2.8.0
  593. tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
  594. if (i2p::fs::Exists(tunConf)) {
  595. LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
  596. } else {
  597. tunConf = i2p::fs::DataDirPath ("tunnels.conf");
  598. }
  599. }
  600. LogPrint(eLogDebug, "tunnels config file: ", tunConf);
  601. try
  602. {
  603. boost::property_tree::read_ini (tunConf, pt);
  604. }
  605. catch (std::exception& ex)
  606. {
  607. LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ());//TODO show err box and disable tunn.page
  608. return;
  609. }
  610. for (auto& section: pt)
  611. {
  612. std::string name = section.first;
  613. try
  614. {
  615. std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
  616. if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
  617. || type == I2P_TUNNELS_SECTION_TYPE_SOCKS
  618. || type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
  619. || type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
  620. || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
  621. {
  622. // mandatory params
  623. std::string dest;
  624. if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
  625. dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
  626. std::cout << "had read tunnel dest: " << dest << std::endl;
  627. }
  628. int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
  629. std::cout << "had read tunnel port: " << port << std::endl;
  630. // optional params
  631. std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, "");
  632. std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1");
  633. int destinationPort = section.second.get<int>(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
  634. std::cout << "had read tunnel destinationPort: " << destinationPort << std::endl;
  635. i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
  636. // I2CP
  637. std::map<std::string, std::string> options;
  638. I2CPParameters i2cpParameters;
  639. ReadI2CPOptions (section, options, i2cpParameters);
  640. tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
  641. dest,
  642. port,
  643. keys,
  644. address,
  645. destinationPort,
  646. sigType);
  647. }
  648. else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
  649. || type == I2P_TUNNELS_SECTION_TYPE_HTTP
  650. || type == I2P_TUNNELS_SECTION_TYPE_IRC
  651. || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
  652. {
  653. // mandatory params
  654. std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
  655. int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
  656. // optional params
  657. std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS, "");
  658. int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
  659. std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
  660. std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
  661. std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
  662. bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
  663. i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
  664. std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
  665. bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
  666. // I2CP
  667. std::map<std::string, std::string> options;
  668. I2CPParameters i2cpParameters;
  669. ReadI2CPOptions (section, options, i2cpParameters);
  670. /*
  671. std::set<i2p::data::IdentHash> idents;
  672. if (accessList.length () > 0)
  673. {
  674. size_t pos = 0, comma;
  675. do
  676. {
  677. comma = accessList.find (',', pos);
  678. i2p::data::IdentHash ident;
  679. ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
  680. idents.insert (ident);
  681. pos = comma + 1;
  682. }
  683. while (comma != std::string::npos);
  684. }
  685. */
  686. tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
  687. host,
  688. port,
  689. keys,
  690. inPort,
  691. accessList,
  692. hostOverride,
  693. webircpass,
  694. gzip,
  695. sigType,
  696. address,
  697. isUniqueLocal);
  698. }
  699. else
  700. LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui
  701. }
  702. catch (std::exception& ex)
  703. {
  704. LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());//TODO show err box and disable the tunn gui
  705. }
  706. }
  707. }
  708. private:
  709. class TunnelsPageUpdateListenerMainWindowImpl : public TunnelsPageUpdateListener {
  710. MainWindow* mainWindow;
  711. public:
  712. TunnelsPageUpdateListenerMainWindowImpl(MainWindow* mainWindow_):mainWindow(mainWindow_){}
  713. virtual void updated(std::string oldName, TunnelConfig* tunConf);
  714. virtual void needsDeleting(std::string oldName);
  715. };
  716. TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener;
  717. void onLoggingOptionsChange() {}
  718. };
  719. #endif // MAINWINDOW_H