Browse Source

moved qt and android sources inn separate repositories

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/1634/head
R4SAS 3 years ago
parent
commit
abe1af7b4f
Signed by: r4sas
GPG Key ID: 66F6C87B98EBCFE2
  1. 18
      android/.gitignore
  2. 60
      android/AndroidManifest.xml
  3. 19
      android/README.md
  4. 693
      android/assets/addressbook/addresses.csv
  5. 1
      android/assets/certificates
  6. 92
      android/assets/i2pd.conf
  7. 3
      android/assets/subscriptions.txt
  8. 33
      android/assets/tunnels.conf
  9. 1
      android/assets/tunnels.d
  10. 105
      android/build.gradle
  11. 96
      android/build.xml
  12. 3
      android/gradle.properties
  13. BIN
      android/gradle/wrapper/gradle-wrapper.jar
  14. 6
      android/gradle/wrapper/gradle-wrapper.properties
  15. 172
      android/gradlew
  16. 84
      android/gradlew.bat
  17. 73
      android/jni/Android.mk
  18. 36
      android/jni/Application.mk
  19. 222
      android/jni/DaemonAndroid.cpp
  20. 97
      android/jni/DaemonAndroid.h
  21. 114
      android/jni/i2pd_android.cpp
  22. 53
      android/jni/org_purplei2p_i2pd_I2PD_JNI.h
  23. 20
      android/proguard-project.txt
  24. 14
      android/project.properties
  25. BIN
      android/res/drawable/icon.png
  26. BIN
      android/res/drawable/itoopie_notification_icon.png
  27. 26
      android/res/layout/activity_perms_asker.xml
  28. 25
      android/res/layout/activity_perms_explanation.xml
  29. 22
      android/res/layout/activity_web_console.xml
  30. 31
      android/res/menu/options_main.xml
  31. 40
      android/res/values-ru/strings.xml
  32. 41
      android/res/values/strings.xml
  33. 16
      android/res/values/template-dimens.xml
  34. 1
      android/settings.gradle
  35. 374
      android/src/org/purplei2p/i2pd/DaemonWrapper.java
  36. 188
      android/src/org/purplei2p/i2pd/ForegroundService.java
  37. 486
      android/src/org/purplei2p/i2pd/I2PDActivity.java
  38. 170
      android/src/org/purplei2p/i2pd/I2PDPermsAskerActivity.java
  39. 38
      android/src/org/purplei2p/i2pd/I2PDPermsExplanationActivity.java
  40. 31
      android/src/org/purplei2p/i2pd/I2PD_JNI.java
  41. 30
      android/src/org/purplei2p/i2pd/NetworkStateChangeReceiver.java
  42. 67
      android/src/org/purplei2p/i2pd/WebConsoleActivity.java
  43. 1
      qt/.gitignore
  44. 13
      qt/i2pd_qt/.gitignore
  45. 21
      qt/i2pd_qt/AboutDialog.cpp
  46. 22
      qt/i2pd_qt/AboutDialog.h
  47. 194
      qt/i2pd_qt/AboutDialog.ui
  48. 7
      qt/i2pd_qt/BuildDateTimeQt.h
  49. 220
      qt/i2pd_qt/ClientTunnelPane.cpp
  50. 126
      qt/i2pd_qt/ClientTunnelPane.h
  51. 195
      qt/i2pd_qt/DaemonQT.cpp
  52. 88
      qt/i2pd_qt/DaemonQT.h
  53. 3
      qt/i2pd_qt/DelayedSaveManager.cpp
  54. 26
      qt/i2pd_qt/DelayedSaveManager.h
  55. 140
      qt/i2pd_qt/DelayedSaveManagerImpl.cpp
  56. 84
      qt/i2pd_qt/DelayedSaveManagerImpl.h
  57. 7
      qt/i2pd_qt/I2pdQtTypes.h
  58. 12
      qt/i2pd_qt/I2pdQtUtil.cpp
  59. 9
      qt/i2pd_qt/I2pdQtUtil.h
  60. 2
      qt/i2pd_qt/MainWindowItems.cpp
  61. 17
      qt/i2pd_qt/MainWindowItems.h
  62. 3
      qt/i2pd_qt/README.md
  63. 6
      qt/i2pd_qt/Saver.cpp
  64. 25
      qt/i2pd_qt/Saver.h
  65. 81
      qt/i2pd_qt/SaverImpl.cpp
  66. 33
      qt/i2pd_qt/SaverImpl.h
  67. 278
      qt/i2pd_qt/ServerTunnelPane.cpp
  68. 183
      qt/i2pd_qt/ServerTunnelPane.h
  69. 2
      qt/i2pd_qt/SignatureTypeComboboxFactory.cpp
  70. 86
      qt/i2pd_qt/SignatureTypeComboboxFactory.h
  71. 67
      qt/i2pd_qt/TunnelConfig.cpp
  72. 260
      qt/i2pd_qt/TunnelConfig.h
  73. 405
      qt/i2pd_qt/TunnelPane.cpp
  74. 191
      qt/i2pd_qt/TunnelPane.h
  75. 12
      qt/i2pd_qt/TunnelsPageUpdateListener.h
  76. 2
      qt/i2pd_qt/data/.gitignore
  77. BIN
      qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png
  78. BIN
      qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png
  79. BIN
      qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png
  80. BIN
      qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png
  81. BIN
      qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png
  82. BIN
      qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png
  83. BIN
      qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png
  84. BIN
      qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png
  85. BIN
      qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png
  86. 57
      qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml
  87. 11
      qt/i2pd_qt/data/website.i2pd.i2pd.desktop
  88. 3810
      qt/i2pd_qt/generalsettingswidget.ui
  89. 6
      qt/i2pd_qt/i2pd.qrc
  90. 32
      qt/i2pd_qt/i2pd.rc
  91. 179
      qt/i2pd_qt/i2pd_qt.pro
  92. 45
      qt/i2pd_qt/logviewermanager.cpp
  93. 130
      qt/i2pd_qt/logviewermanager.h
  94. 1126
      qt/i2pd_qt/mainwindow.cpp
  95. 883
      qt/i2pd_qt/mainwindow.h
  96. 1053
      qt/i2pd_qt/mainwindow.ui
  97. 24
      qt/i2pd_qt/pagewithbackbutton.cpp
  98. 21
      qt/i2pd_qt/pagewithbackbutton.h
  99. BIN
      qt/i2pd_qt/resources/icons/mask.ico
  100. BIN
      qt/i2pd_qt/resources/images/icon.png
  101. Some files were not shown because too many files have changed in this diff Show More

18
android/.gitignore vendored

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
gen
tests
bin
libs
log*
obj
.cxx
.gradle
.idea
.externalNativeBuild
ant.properties
local.properties
build.sh
android.iml
build
*.iml
*.local
*.jks

60
android/AndroidManifest.xml

@ -1,60 +0,0 @@ @@ -1,60 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.purplei2p.i2pd"
android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
android:usesCleartextTraffic="true">
<meta-data
android:name="android.webkit.WebView.MetricsOptOut"
android:value="true"/>
<activity android:name=".WebConsoleActivity"></activity>
<receiver android:name=".NetworkStateChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<activity
android:name=".I2PDPermsAskerActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".I2PDActivity"
android:label="@string/app_name" />
<service
android:name=".ForegroundService"
android:enabled="true" />
<activity
android:name=".I2PDPermsExplanationActivity"
android:label="@string/title_activity_i2_pdperms_asker_prompt"
android:parentActivityName=".I2PDPermsAskerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" />
</activity>
</application>
</manifest>

19
android/README.md

@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
# how to compile?
## Install the gradle + NDK or use android-studio
[https://gradle.org/install/](https://gradle.org/install/)
## Install the depencies
```
git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
git clone https://github.com/PurpleI2P/android-ifaddrs.git
git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
```
## Set libs in jni/Application.mk on 24 line:
```
# change to your own
I2PD_LIBS_PATH = /home/user/i2pd/android/
```
## compile apk file
gradle clean assembleRelease

693
android/assets/addressbook/addresses.csv

@ -1,693 +0,0 @@ @@ -1,693 +0,0 @@
00.i2p,zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq
0ipfs.i2p,cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza
0xcc.i2p,gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq
1.fcp.freenet.i2p,cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq
102chan.i2p,xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq
1st.i2p,rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq
2.fcp.freenet.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
333.i2p,ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza
55cancri.i2p,b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua
adab.i2p,pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha
alice.i2p,iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq
always.i2p,wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq
amazone.i2p,e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa
amiga.i2p,edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q
amobius.i2p,rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq
anarchistfaq.i2p,xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q
animal.i2p,5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla
anodex.i2p,25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a
anoncoin.i2p,nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa
anongw.i2p,owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq
anonsfw.i2p,ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq
anonymnet.i2p,77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa
anonynanny.i2p,l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja
anonyradio.i2p,cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq
antipiracyagency.i2p,by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq
antipiratbyran.i2p,y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a
aosp.i2p,ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q
arc2.i2p,rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na
archaicbinarybbs.i2p,t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa
archiv.tutorials.i2p,lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq
archive.i2p,x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq
archive.syndie.i2p,abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq
ardor-wallet.i2p,tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq
ardvark.i2p,jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq
arf.i2p,o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq
arkan.i2p,7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq
asciiwhite.i2p,itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq
aspnet.i2p,tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a
asylum.i2p,p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha
auchan.i2p,6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a
aum.i2p,ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq
awup.i2p,v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga
b.i2p,272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq
bacardi.i2p,hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq
backup.i2p,kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq
badfish.i2p,f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a
badtoyz.i2p,3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna
barry.i2p,4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq
bash.i2p,s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q
bdl.i2p,kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a
bdsm.i2p,pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq
betaguru.i2p,d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq
beyond.i2p,uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa
bible.i2p,pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda
bible4u.i2p,xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq
bigbrother.i2p,tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq
bitlox.i2p,lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq
bittorrent.i2p,pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q
bk1k.i2p,nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq
bl.i2p,e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a
black.i2p,sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq
blackbox.i2p,7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa
blackexchange.i2p,ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q
blog.curiosity.i2p,yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta
blog.polecat.i2p,orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq
blog.tinlans.i2p,ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda
bluebeam.i2p,lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a
blueheron.i2p,anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa
bnc.i2p,fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa
bob.i2p,i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa
bobcat.i2p,ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq
bobthebuilder.i2p,qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q
boerse.i2p,7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq
bofh.i2p,auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a
boing.i2p,bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a
books.manveru.i2p,eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq
bote.i2p,bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a
bozo.i2p,7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq
brittanyworld.i2p,e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa
bt.i2p,uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq
bugfuzz.i2p,ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq
burntout.i2p,lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq
bytepay.i2p,7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq
ca.i2pd.i2p,u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba
cases.i2p,kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a
cathugger.i2p,vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba
cbs.i2p,u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq
cerapadus.i2p,zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq
cerebrum.i2p,u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq
cgan.i2p,43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa
chat.i2p,ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq
chess.fillament.i2p,tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya
chess.i2p,sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa
china.i2p,wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq
chitanka.i2p,u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba
ciaran.i2p,2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna
ciphercraft.i2p,7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca
closedshop.i2p,6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq
cneal.i2p,g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba
co.i2p,3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q
codevoid.i2p,2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa
colombo-bt.i2p,cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa
complication.i2p,x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a
comwiz.i2p,6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq
confessions.i2p,lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa
connelly.i2p,5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq
costeira.i2p,abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa
cowsay.i2p,q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q
crstrack.i2p,mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja
crypthost.i2p,zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca
crypto.i2p,vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta
cryptostorm.i2p,mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq
curiosity.i2p,eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq
cvs.i2p,yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba
danwin1210.i2p,eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba
darknetnow.i2p,gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q
darknut.i2p,2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya
darkrealm.i2p,gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq
darrob.i2p,hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja
dashninja.i2p,dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma
davidkra.i2p,nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a
dcherukhin.i2p,qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a
de-ebook-archiv.i2p,6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q
de-ebooks.i2p,epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq
dead.i2p,7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq
deadgod.i2p,63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa
debian-multimedia.i2p,cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq
decadence.i2p,pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq
deepwebradio.i2p,2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la
def2.i2p,cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da
def3.i2p,xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la
def4.i2p,yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq
deploy.i2p,ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a
det.i2p,y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q
detonate.i2p,nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja
dev.i2p,cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna
di.i2p,3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa
diasporg.i2p,edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua
diftracker.i2p,m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka
dm.i2p,heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq
docs.i2p,ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za
docs.i2p2.i2p,las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna
downloads.legion.i2p,xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq
dox.i2p,vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a
dropbox.i2p,omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq
duck.i2p,3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua
dumpteam.i2p,2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa
dust.i2p,u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq
dvdr-core.i2p,fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q
dyad.i2p,7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka
e-reading.i2p,z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq
easygpg2.i2p,bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora
eboochka.i2p,ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq
ebooks.i2p,bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq
echelon.i2p,afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq
echo.baffled.i2p,bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha
eco.i2p,2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa
eddysblog.i2p,ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq
edge.i2p,aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta
eepdot.i2p,t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa
eepshare-project.i2p,sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq
eepsites.i2p,isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq
elf.i2p,duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa
elgoog.i2p,z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya
ems.i2p,734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q
epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
es.hiddenanswers.i2p,cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa
eschaton.i2p,xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q
esuwiki.i2p,cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa
evil.i2p,ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a
evilchat.i2p,s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla
evilgit.i2p,mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla
exch.i2p,vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq
exchange.gostcoin.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
exchanged.i2p,ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra
exitpoint.i2p,5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta
exotrack.i2p,blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva
explorer.gostcoin.i2p,ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za
fa.i2p,6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka
falafel.i2p,djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq
false.i2p,77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha
false2.i2p,j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa
fantasy-worlds.i2p,62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq
fcp.entropy.i2p,de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq
fcp.i2p,ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
fedo.i2p,zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq
feedspace.i2p,kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa
ferret.i2p,kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q
fido.r4sas.i2p,i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q
fifi4all.i2p,v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa
files.hypercubus.i2p,qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa
files.i2p,w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa
files.nickster.i2p,yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq
fillament.i2p,udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq
firerabbit.i2p,awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q
flibs.i2p,ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a
flibusta.i2p,zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq
flipkick.i2p,aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq
flock.i2p,hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q
floureszination.i2p,vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq
forum.fr.i2p,onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq
forum.i2p,33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya
forum.rus.i2p,zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga
forums.i2p,tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya
fproxy.i2p,keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a
fproxy.tino.i2p,fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha
fproxy2.i2p,r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza
fr.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
freeciv.nightblade.i2p,rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta
freedomarchives.i2p,4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q
freedomforum.i2p,abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua
freefallheavens.i2p,giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq
freenet.eco.i2p,2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a
freshcoffee.i2p,sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q
frooze.i2p,m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja
frosk.i2p,63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq
frostmirror.i2p,ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq
fs.i2p,ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q
fsoc.i2p,vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q
galen.i2p,4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q
gaming.i2p,rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q
garden.i2p,qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq
gaytorrents.i2p,fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q
general.i2p,5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq
gernika.i2p,wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a
ginnegappen.i2p,kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja
git-ssh.crypthost.i2p,llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a
git.crypthost.i2p,7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa
git.psi.i2p,em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa
git.repo.i2p,vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq
git.volatile.i2p,gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq
glog.i2p,ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq
gloinsblog.i2p,zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a
go.i2p,ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q
gonzo2000.i2p,nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a
google.i2p,4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq
gostcoin.i2p,4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq
gott.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
greenflog.i2p,zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq
gstbtc.i2p,n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
gusion.i2p,4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta
guttersnipe.i2p,kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq
hack8.i2p,un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq
hagen.i2p,e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q
heisenberg.i2p,jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq
heligoland.i2p,gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq
hidden.i2p,iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq
hiddenanswers.i2p,kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq
hiddenbooru.i2p,zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q
hiddenchan.i2p,6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa
hiddengate.i2p,rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq
home.duck.i2p,jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma
hopekiller.i2p,kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa
hotline.i2p,6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq
hq.postman.i2p,27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq
http.entropy.i2p,ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq
human.i2p,nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa
i2host.i2p,awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q
i2jump.i2p,633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa
i2p-bt.postman.i2p,jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla
i2p-epub-eepsite.i2p,yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
i2p-javadocs.i2p,icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq
i2p-projekt.i2p,udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna
i2pbote.i2p,tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a
i2pbuggenie.i2p,bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q
i2pchan.i2p,tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq
i2pd.i2p,4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa
i2pdocs.str4d.i2p,yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq
i2peek-a-boo.i2p,qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa
i2pforum.i2p,tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda
i2pjump.i2p,2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka
i2plugins.i2p,bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a
i2pmetrics.i2p,v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a
i2pnews.i2p,tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq
i2podisy.i2p,3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq
i2push.i2p,mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq
i2pwiki.i2p,nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq
iamevil.i2p,au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja
icu812.i2p,bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva
id3nt.i2p,ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q
identiguy.i2p,3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva
ilcosmista.i2p,6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q
ilita.i2p,isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba
illuminati.i2p,syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla
imhotep.i2p,qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a
in.i2p,r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq
infosecurity.i2p,v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba
infoserver.i2p,jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q
inproxy.tino.i2p,ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma
inr.i2p,joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq
instantexchange.i2p,5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq
investigaciones.i2p,n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha
invisible-internet.i2p,jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq
io.i2p,tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q
irc.00.i2p,bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq
irc.arcturus.i2p,5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq
irc.baffled.i2p,5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq
irc.carambar.i2p,hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq
irc.cerapadus.i2p,e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq
irc.dg.i2p,fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq
irc.duck.i2p,chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq
irc.echelon.i2p,ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq
irc.freshcoffee.i2p,ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa
irc.i2p,l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq
irc.ilita.i2p,5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a
irc.ircbnc.i2p,4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa
irc.killyourtv.i2p,wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq
irc.nickster.i2p,dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a
irc.orz.i2p,7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq
irc.postman.i2p,mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq
irc.r4sas.i2p,hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la
ircssl.cerapadus.i2p,4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea
irongeeks.i2p,ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a
iscofsi.i2p,enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq
isotoxin.i2p,wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq
itemname.i2p,o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq
ivorytower.i2p,fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq
j.i2p,kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea
jabber-2.i2p,pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na
jabber.duck.i2p,rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq
jake.i2p,v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq
jar.i2p,2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq
jazzy.i2p,ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa
jdot.i2p,kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq
jhor.i2p,c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa
jikx.i2p,aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq
jisko.i2p,jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca
jmg.i2p,oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq
jnymo.i2p,nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda
jrandom.dev.i2p,htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq
jrandom.i2p,dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
jrrecology.i2p,qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq
jwebcache.i2p,xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa
k1773r.i2p,zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq
kaji.i2p,z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq
kaji2.i2p,4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a
keys.echelon.i2p,mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva
keys.i2p,6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba
keyserver.sigterm.i2p,isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga
killyourtv.i2p,aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda
knijka.i2p,knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa
knotwork.i2p,2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq
kohaar.i2p,qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q
krabs.i2p,3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca
kuroneko.i2p,wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq
kycklingar.i2p,gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva
lazyguy.i2p,ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
legion.i2p,5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq
legwork.i2p,cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a
lenta.i2p,nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra
libertor.i2p,7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq
library.i2p,brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a
lifebox.i2p,pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq
linuxagent.i2p,ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq
lists.i2p2.i2p,vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua
lm.i2p,yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q
lodikon.i2p,u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a
lolicatgirls.i2p,a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla
lolifox.i2p,7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca
longhorn.i2p,pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a
lp.i2p,jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq
lucky.i2p,wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa
luckypunk.i2p,y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka
lunokhod.i2p,3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa
m16.i2p,ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva
mac7.i2p,3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q
madman2003.i2p,a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq
magix.i2p,cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq
magnets.i2p,snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca
manas.i2p,6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba
manveru.i2p,pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq
marcos.i2p,vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq
marshmallow.i2p,svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q
marxists.i2p,lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq
mattermost.i2p,x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya
me.i2p,dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na
meeh.i2p,4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa
mesh.firerabbit.i2p,3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq
messageinabottle.i2p,avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a
metrics.i2p,z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq
mhatta.i2p,o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq
microbleu.i2p,mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa
microsoft.i2p,hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza
mindisl0st.i2p,u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a
mindspore.i2p,uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q
modulus.i2p,ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a
monerotools.i2p,5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q
monerujo.i2p,puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq
morph.i2p,iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa
mosbot.i2p,5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a
mosfet.i2p,s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q
moxonom.i2p,gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq
mp3.aum.i2p,n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq
mp3.tc.i2p,w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa
mpaa.i2p,m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya
mrbamboo.i2p,tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa
mrflibble.i2p,u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq
mrplod.i2p,fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq
mtn.i2p,xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq
mtn.i2p-projekt.i2p,f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa
mtn.i2p2.i2p,l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a
mtn.meeh.i2p,h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la
mudgaard.i2p,yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq
mush.zeit.i2p,dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha
music.i2p,akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia
mysterious.i2p,p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq
mywastedlife.i2p,ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq
nacl.i2p,bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia
nano.i2p,ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba
nassai.i2p,v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q
neodome.i2p,5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq
news-i2pn.i2p,wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca
news.neodome.i2p,trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq
news.underscore.i2p,rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q
newsbyte.i2p,gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq
nibble.i2p,jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa
nic.i2p,vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq
nickster.i2p,zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq
nickster2.i2p,eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq
nickyb.i2p,gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa
nightblade.i2p,p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha
ninja.i2p,q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya
nm.i2p,3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya
nntp.baffled.i2p,kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a
nntp.duck.i2p,gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q
nntp.fr.i2p,npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva
nntp.i2p,wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q
no.i2p,lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba
noname56.i2p,oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa
nop.i2p,ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca
normal.i2p,j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma
normanabcd.i2p,si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a
nothingburger.i2p,tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq
nothingspecial.i2p,wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga
novospice.i2p,ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq
nsa.i2p,nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga
nvspc.i2p,anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra
nxt-wallet.i2p,33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a
obmen.i2p,vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa
obscuratus.i2p,i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota
ogg.aum.i2p,wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q
ogg.baffled.i2p,tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq
ol.i2p,bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq
onboard.i2p,qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq
onelon.i2p,irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha
onhere.i2p,vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva
oniichan.i2p,nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq
onionforum.i2p,yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q
ooo.i2p,iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a
opal.i2p,li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa
open4you.i2p,ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a
opendiftracker.i2p,bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq
openforums.i2p,lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q
opentracker.dg2.i2p,w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa
orion.i2p,5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga
orz.i2p,oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq
os3.i2p,s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq
osiristomb.i2p,t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq
ot.knotwork.i2p,cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq
outproxy-tor.meeh.i2p,77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq
outproxy.h2ik.i2p,nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza
outproxyng.h2ik.i2p,v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq
overchan.oniichan.i2p,g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya
p4bl0.i2p,lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga
pants.i2p,xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq
papel.i2p,mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq
pasta-nojs.i2p,dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la
paste.crypthost.i2p,2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq
paste.i2p2.i2p,b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq
paste.r4sas.i2p,csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa
pastebin.i2p,mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa
pastethis.i2p,erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha
pdforge.i2p,wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq
perv.i2p,f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq
pgp.duck.i2p,wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha
pharos.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
pharoz.i2p,vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
phonebooth.i2p,noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq
photo.i2p,fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq
piespy.i2p,vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a
pisekot.i2p,7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq
pizdabol.i2p,5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa
planet.i2p,y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq
plugins.i2p,wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia
polecat.i2p,het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq
politguy.i2p,6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq
pomoyka.i2p,omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q
pool.gostcoin.i2p,m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa
pop.mail.i2p,bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq
pop.postman.i2p,ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya
pravtor.i2p,2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq
pris.i2p,ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a
project-future.i2p,ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta
projectmayhem2012-086.i2p,ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq
protokol.i2p,f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq
proxynet.i2p,7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a
psi.i2p,avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a
psy.i2p,s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q
psyco.i2p,eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q
pt.hiddenanswers.i2p,o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a
ptm.i2p,7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa
ptt.i2p,q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha
pull.git.repo.i2p,3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q
push.git.repo.i2p,jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a
pycache.awup.i2p,w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra
r4sas.i2p,2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq
radio.r4sas.i2p,cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla
ragnarok.i2p,jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca
ransack.i2p,mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq
rasputin-sucks.i2p,fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq
rebel.i2p,nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq
red.i2p,fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa
redpanda.i2p,3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea
redzara.i2p,ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va
reefer.i2p,4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa
relatelist.i2p,utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq
repo.i2p,uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa
repo.r4sas.i2p,ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq
reseed.i2p,j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq
retrobbs-nntp.i2p,fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q
retrobbs.i2p,mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq
retrobbs2.i2p,ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q
revo-ua.i2p,hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq
riaa.i2p,lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa
rideronthestorm.i2p,xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq
romster.i2p,eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a
rootd.i2p,mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq
rospravosudie.i2p,z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q
rotten.i2p,j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq
rpi.i2p,56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq
rslight.i2p,bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq
rsync.thetower.i2p,w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa
ru.hiddenanswers.i2p,o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva
ru.i2p,m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja
rufurus.i2p,7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca
rus.i2p,gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga
ruslibgen.i2p,kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq
rutor.i2p,tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq
salt.i2p,6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq
sasquotch.i2p,p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q
schwarzwald.i2p,4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq
sciencebooks.i2p,ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq
scp.duck.i2p,ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda
search.i2p,nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q
secretchat.i2p,cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q
secure.thetinhat.i2p,4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala
seeker.i2p,ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq
seomon.i2p,5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q
septu.i2p,5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra
serien.i2p,3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda
ses.i2p,5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja
shiftfox.i2p,wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq
shoieq3.i2p,3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q
shoronil.i2p,7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa
short.i2p,z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba
sion.i2p,lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q
sirup.i2p,aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma
site.games.i2p,zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja
skank.i2p,qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q
slack.i2p,gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja
slacker.i2p,wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq
smeghead.i2p,ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja
smtp.mail.i2p,kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya
smtp.postman.i2p,jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q
socks1.tor.i2p,sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq
sonax.i2p,jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq
sponge.i2p,o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq
squid.i2p,r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq
squid2.i2p,hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila
sqz.i2p,3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq
ssh.i2p,xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq
stasher.i2p,6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa
stats.i2p,7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq
status.str4d.i2p,ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q
sto-man.i2p,rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa
str4d.i2p,wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa
stream.i2p,prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna
streams.darkrealm.i2p,ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq
striker.i2p,4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq
subrosa.i2p,g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq
subterra.i2p,vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq
sugadude.i2p,yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq
suicidal.i2p,yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq
sungo.i2p,h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q
surrender.adab.i2p,jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta
susi.i2p,qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq
syncline.i2p,5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra
syndie-project.i2p,xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq
syndie.echelon.i2p,vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta
syndie.i2p,7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq
syndiemedia.i2p,4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma
tabak.i2p,y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia
tahoeserve.i2p,yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa
tc.i2p,qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a
telegram.i2p,i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja
templar.i2p,zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q
terror.i2p,wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq
thebland.i2p,oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda
thebreton.i2p,woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq
thedarkside.i2p,fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca
theland.i2p,26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa
thetower.i2p,3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a
thornworld.i2p,vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva
tino.i2p,e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq
tinyurl.i2p,mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa
tome.i2p,qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq
tor-gw.meeh.i2p,ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza
tor-www-proxy.i2p,xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q
torapa.i2p,eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta
torrentfinder.i2p,mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq
torrfreedom.i2p,nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq
trac.i2p,kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca
trac.i2p2.i2p,i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa
tracker-fr.i2p,qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea
tracker.awup.i2p,dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq
tracker.crypthost.i2p,ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq
tracker.fr.i2p,rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q
tracker.i2p,lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q
tracker.lodikon.i2p,q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra
tracker.mastertracker.i2p,tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda
tracker.postman.i2p,jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq
tracker.psi.i2p,vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa
tracker.thebland.i2p,s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq
tracker.welterde.i2p,cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa
tracker2.postman.i2p,ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna
traditio.i2p,wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq
trevorreznik.i2p,wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma
true.i2p,pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq
trwcln.i2p,evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq
trypanom.i2p,tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q
ts.i2p,nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq
ttc.i2p,wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq
ttp.i2p,uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a
tumbach.i2p,u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq
tutorials.i2p,zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja
ugha.i2p,z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda
uk.i2p,vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a
underground.i2p,dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica
underscore.i2p,3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa
unqueued.i2p,3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq
up.i2p,25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q
update.dg.i2p,iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja
update.killyourtv.i2p,gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq
update.postman.i2p,u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq
utansans.i2p,u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda
v2mail.i2p,4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a
vadino.i2p,aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra
visibility.i2p,pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq
volatile.i2p,q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a
vpnbest.i2p,ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea
vudu.i2p,3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q
w.i2p,j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq
wa11ed.city.i2p,7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa
wahoo.i2p,vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa
wallet.gostcoin.i2p,reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda
wallsgetbombed.i2p,tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq
web.telegram.i2p,re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a
wiht.i2p,yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca
wiki.fr.i2p,lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq
wiki.ilita.i2p,r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a
wintermute.i2p,4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila
wspucktracker.i2p,ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq
www.aum.i2p,3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq
www.baffled.i2p,lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq
www.fr.i2p,rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea
www.i2p,ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va
www.i2p2.i2p,rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga
www.imule.i2p,657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq
www.infoserver.i2p,fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq
www.janonymous.i2p,vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq
www.mail.i2p,nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba
www.nntp.i2p,kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka
www.postman.i2p,rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq
www.syndie.i2p,vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva
www1.squid.i2p,vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa
xc.i2p,mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq
xeha.i2p,oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq
xilog.i2p,eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq
xmpp.crypthost.i2p,ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba
xmpp.rpi.i2p,3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca
xn--l2bl5aw.i2p,d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa
xolotl.i2p,rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq
xotc.i2p,gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq
z-lab.i2p,s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba
zab.i2p,n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq
zcash.i2p,zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q
zener.i2p,mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca
zerobin.i2p,3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq
zeroman.i2p,gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq
zeronet.i2p,fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna
znc.i2p,uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa
znc.str4d.i2p,ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq
zzz.i2p,ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq
1 00.i2p zmzpltxslembpaupg3srh4bbhv5txgh5jmms6sfj4hzsvlv3xugq
2 0ipfs.i2p cdii3ou5mve5sfxyirs6kogt4tbvivk2d6o25awbcbazjrlhjeza
3 0xcc.i2p gawouxh2sg32cluwlqsnpy3dwedvoqtfroi4evvdvm2pfv7tdadq
4 1.fcp.freenet.i2p cuxbeputgxn75ak4nr7ltp7fjktnzl5sul3wstwnsoytbbpb4ixq
5 102chan.i2p xxu3lso4h2rh6wmrxiou3ax7r7la7x6dhoepnku3jvrlwp35pefq
6 1st.i2p rduua7bhest6rwsmmyttzssfdw3p4eu6bgl3mb4hin32qo3x5zfq
7 2.fcp.freenet.i2p ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
8 333.i2p ctvfe2fimcsdfxmzmd42brnbf7ceenwrbroyjx3wzah5eudjyyza
9 55cancri.i2p b4iqenefh2fr4xtuq6civfc6nhnia6e2yo36pf7vcgdvrwmh7xua
10 adab.i2p pxjr6f2cig6v7v7ekam3smdnkqgmgseyy5cdwrozdyejm7jknkha
11 alice.i2p iq26r2ls2qlkhbn62cvgb6a4iib7m5lkoulohdua5z6uvzlovjtq
12 always.i2p wp43sdtuxum6gxbjvyeor35r5yvgtkp3dcu7dv47lx22zeb3relq
13 amazone.i2p e6kq73lsxaeyiwpmykdbdo3uy4ppj64bl7y3viegp6mqrilqybqa
14 amiga.i2p edy2xappzjjh7bxqounevji4wd2binqkv7gft4usrkan45xhbk5q
15 amobius.i2p rj6432agdprun5baai2hj62xfhb4l75uvzl55dhj6z5zzoxv3htq
16 anarchistfaq.i2p xosberjz2geveh5dcstztq5kwew6xx2brrqaorkjf2323bjzcd3q
17 animal.i2p 5iedafy32swqq4t2wcmjb4fvg3onscng7ct7wb237jkvrclaftla
18 anodex.i2p 25cb5kixhxm6i6c6wequrhi65mez4duc4l5qk6ictbik3tnxlu6a
19 anoncoin.i2p nmi3loretkk4zbili32t2e5wyznwoxcsgzmd2z4ll3msgndyqpfa
20 anongw.i2p owrnciwubb3f3dctvlmnaknb6tjdxtlzvv7klocb45mmhievdjhq
21 anonsfw.i2p ir6hzi66izmvqx3usjl6br3nndkpazonlckrzt3gtltqcy5ralyq
22 anonymnet.i2p 77ouyl2ane7ffgydosd4ye42g67aomtc4jrusmi76lds5qonlffa
23 anonynanny.i2p l2lnhq2dynnmf3m46tcbpcmbbn4kifjgt26go6n2hlapy4drhyja
24 anonyradio.i2p cbobsax3rhoyjbk7ii2nd2fnl5bxh3x7bbearokyxgvmudn7o5bq
25 antipiracyagency.i2p by4kcmklz7xnkai6ndfio47kts3rndm6wwleegtxghllimikdapq
26 antipiratbyran.i2p y2qbhrvuciifbszaqqwxd5t75bomp7kzdqx4yxsrkaq542t75k3a
27 aosp.i2p ly7raldsh2na2cgw5yvueyvqqjgx3vbqinecjrqdldgya76i2p2q
28 arc2.i2p rnmosuwvtftfcrk5sk7zoyhyadh2g4dhe2mif5ml7qjisgkyw2na
29 archaicbinarybbs.i2p t7o2tw36cffedgfr6kahewpkrntofnliuapji2e4rucl3os55epa
30 archiv.tutorials.i2p lldr2miowq6353fxy44pnxfk37d6yn2f6kaivzecbmvvnnf5exyq
31 archive.i2p x54d5st3dl6mwgfxj6raiekqkypo5pdvuex3n62szwju7hgefiyq
32 archive.syndie.i2p abbyu5n3mh3nj7pe3b6byldrxswvva5ttxcafsnnseidanurq3kq
33 ardor-wallet.i2p tm23k5ny3umhf6vf3kghnnwacli5zywq5wrr3xcqowbcofuyr4gq
34 ardvark.i2p jcmw2sol3hruwc6rfinonx4e23pjkukkg7lg7xt7xb2gpiyyraiq
35 arf.i2p o46lsq4u7udxg3qqlidrmpj4lb4nr7ldxmbb2x53nftndaeyxqeq
36 arkan.i2p 7o5y2lyyrjx5tf6l4fyumywui7msjv5azaaheatvw5sqj7mxbuvq
37 asciiwhite.i2p itbzny5ktuenhjwjfqx3jravolhlj5wullhhr2m4qr6k2emnm5dq
38 aspnet.i2p tsb7zqru57p4q2a7cto2lko4w5cg4lieglwm6t27c44fkphqmf2a
39 asylum.i2p p45ejjw4p2q6nq3mzi6cm6ep35grtzshboidj2lojmrmic22noha
40 auchan.i2p 6vxz4yp3vhjwbkmxajj7wiikxafwujig63gkhjknbq6xh4rqpm5a
41 aum.i2p ohdfneqxapfd3fwfbum4tut7z6k3rnr7rrguoxdrrfe2tln2kpbq
42 awup.i2p v6g32duzrkacnrezfbll3pza5u37h7lnukr2wbsk6rqen6prhbga
43 b.i2p 272kt3gcx6wjurunzaiiwld7s5p4mpjewfubzmlcvw2vie62ckpq
44 bacardi.i2p hivhnx2v47vh234c7coi2urj5cyvbl4bu3ypjr7snklortyqeljq
45 backup.i2p kepphem42whle3rkfv26wcksmnegdbg6rdp6t3oobdkc2fmzrdkq
46 badfish.i2p f6v26gyr4eipy3a7pi2voulw5qvob6dg7zij6xpo2ywbi5tvbu6a
47 badtoyz.i2p 3qz6ubtwlt2c4iasofjirkckq43u5fgkzyg7mlutcsym5gzhijna
48 barry.i2p 4kyahq53ol52n23l44tefgeaxqpp3cbb632t5k3umdvqcooevdzq
49 bash.i2p s3wouoilbl3mrefxjhp4qoyujgok34e7y6vmpbu6hx4342ivqo4q
50 bdl.i2p kp6fnuulenbjm7r26pfbmjcq3u7c7kvxeajodvgr5flcnskdgi5a
51 bdsm.i2p pa7fxql5jljegg7j5tglhnnaod2sptq3gxvdn3ji6muqyhgn3poq
52 betaguru.i2p d7cduwwhrcc2voameqfkvd66u3advu4jw2p6pysgax35vq6ovriq
53 beyond.i2p uaicfqlrpjtitqbqkpfujanj5dollzfzee5glsuls67ekw6hlpoa
54 bible.i2p pypz7ca24n3lyp4tm3kvncg3ltp3gd5pgnacc6zltoeffiyyegda
55 bible4u.i2p xs6lr2g5jiaajtb3nkno2zmy34eipitrggooxb7wtey7uko7bqmq
56 bigbrother.i2p tnxiifs6uticzyg6ac4lhv2l5luwi6xra7yngocro56ive5e4jsq
57 bitlox.i2p lqw5khxcdntlv3u4vhn53upcqirplvnc4etjlmoytrzs66ytettq
58 bittorrent.i2p pgax2vz572i4zsp6u6paox5xubmjrkqohq6g4hvlp6ruzzy56l5q
59 bk1k.i2p nlyegmtyfffo5jfgg5h4dxxnlmqko2g36gpaye5a7vd3is35xxfq
60 bl.i2p e73d6uhnfbylza6wqkhxejmqeyfb7thkzw35gn5ojmna64jzyk2a
61 black.i2p sjwueu62qpe6dtv5b322k3f23fl4uz3w6qe6wcrwauiwpnymypfq
62 blackbox.i2p 7josyf7zjieoib3ovmr5a4dh5w64kmfh45lv5h436eljtgfegtqa
63 blackexchange.i2p ztgr5kghkyn43fhhkuycroxgfti6cojo3vg4wdd3usqonyvrla5q
64 blog.curiosity.i2p yiz6jec5k7ccxdgnh7msqa4ze52bqqmf6rpq6bqdyojra2erd4ta
65 blog.polecat.i2p orlccceubewvxo3fbdyydq6e4uuidbs4xd5u2gyqbculnowo3ehq
66 blog.tinlans.i2p ylkch2nkrwehakx4z6wiyjbeqwlgasknukdkex6r6yq4xusrjnda
67 bluebeam.i2p lvxp3cbcfwtol57d5pmrsck32t7ndutlxubjb4smaf32bynhlk6a
68 blueheron.i2p anfb5jrhixjmvkyxctqwkezqer7dbob22wge2bh6wsewbhgnftfa
69 bnc.i2p fr4zbcygmx2vdct6nrabakfys4b4derm6jqu2ovppkgqillvlqxa
70 bob.i2p i76m7dwm5hnapljendbie6fc5y3mjlkdlduo3tvbwiwmvhxbpyaa
71 bobcat.i2p ftuukjtcquuvppt726w37boit7gp5hf2yxwfop35prx3grzzzxlq
72 bobthebuilder.i2p qlahgthqhr4uojkkwahnper2cl3ro5f5gtzy5t4lzapbzo4osy6q
73 boerse.i2p 7633w56hd53sesr6b532r5qlbdnvyl5bnvama6ign6xryaxol4rq
74 bofh.i2p auvuinzogu6gc4pwsgbjijuszxgcjygciu2wy53pfz7mo5nfpc5a
75 boing.i2p bgsq33bh74j66hn4oh7oovlvuhhdyw22lq2qi2fnv3jyh2ryap3a
76 books.manveru.i2p eb2tisc2vr5jvjqrixrozcujiucwxg4m722stxwho5666ipl67zq
77 bote.i2p bhjhc3lsdqzoyhxwzyrd63kvyg4br6n2337d74blyintae66mr2a
78 bozo.i2p 7a2d23h6htprhzrol36vgwgklsbqrnuya4tbaaaspmaeaodt57iq
79 brittanyworld.i2p e76umhhic3474sdxiuax25ixyfg7y3z7oojj4fmxvhgv3ruet6aa
80 bt.i2p uhkuu54pg47zey76h45tnvsdtpkf5bthbtrjgnaloi5m54h4hlaq
81 bugfuzz.i2p ubszn4gsf22vga67rvzzlg4qj2bfcq6o52fmxz46xruawqm6z7rq
82 burntout.i2p lkep3fd7tjvxrs25crr2c3jy7xm4s7bqiua5r327zgpw37sgyerq
83 bytepay.i2p 7amc4ztwkzu3cgsaaaw3223ohuihn5hlsqc6gpf2rxdyptdkyugq
84 ca.i2pd.i2p u5safmawcxj5vlrdtqrsqbsndkr5cfenpicgg5euu4xqm73yicba
85 cases.i2p kmpmk2fmineaiwublteqlifg4fkmewnhmxqlcgg7qwecz6daj43a
86 cathugger.i2p vq43xjjcnejqpzfprws5qzrea2siieshu4tglpdepql2w3w3bpba
87 cbs.i2p u3lp7wazvq6opodzwjg5sc5w5kwxehmxd4wcdpt4s4j2k4dx4apq
88 cerapadus.i2p zroed2cxga5zeuu6rcvmp2yfi77nzduw7yhdplbeuqkuyxwbrzaq
89 cerebrum.i2p u5gtsfn267udwfh2uq35jiabkufifvcbgv456zz34cydutsiw2eq
90 cgan.i2p 43z65gdr52xe3fxmkumwp3dzhedu4tu4rdtzr24hz5b4awcpfbqa
91 chat.i2p ollpwnp6yidc3obbb3famgt6rw5jg5w3k3a6z7hhaegj6gcohiuq
92 chess.fillament.i2p tv6wbanei647yf5bie4dhg2wmybkjurezlpdfwftc5ajqlfswwya
93 chess.i2p sbnoqznp5yzxals3vs6nzyqaj2fetvonys4e3b3x4ktmfeus54sa
94 china.i2p wit6f2zx6dtuqqze6nhbykrds3idppfirxvhf2f7ydqoqf4xdzeq
95 chitanka.i2p u4s3jneepk3akoez46kqiwikoezi6zyj2ibjkjyi4uuvsbcojzba
96 ciaran.i2p 2r3645eete6xwbfu62ogonudcrcgqq25sbnij5v4geru74yrscna
97 ciphercraft.i2p 7s5pkqbpbfdkxtwuu2e2iwstbikyewvvscy76lij4x5pfbygbjca
98 closedshop.i2p 6fg67mbw2okopzyonsck4bsy3cy7l2fame56uiysr2cezhjhzdbq
99 cneal.i2p g4za73ffigv3ht4jnhzy4dae52djjq7lqcguqsfg3w5cxzqm7nba
100 co.i2p 3mvo5eifcwplcsoubtvqkzdahwo2sdhfygfdde7lj2glybk4q22q
101 codevoid.i2p 2mukrqwtinsw27uoejtrz74zxtilyhnnfdyso7j3yo6vaa6nzlaa
102 colombo-bt.i2p cyr75zgiu2uuzap5zeosforbgvpfbqos2g6spe4qfulvzpyhnzxa
103 complication.i2p x2av6rwj5e5tp64yhdmifdyleo4wblw4ncrrcrabxwscuevpdv7a
104 comwiz.i2p 6p7zqfotzbd66etl5xqy3p6xvr5ijucru3am2xqa7wmnj6vf3djq
105 confessions.i2p lh5vitshufxpmyr44zgyymebo5elc42eda7pxvn5lmtes47c7rxa
106 connelly.i2p 5yrris3nigb3fapvzrlrcaew6cdmzdknzvgrc7y2jpn3ntqurweq
107 costeira.i2p abhty5xlmnyab2kqdxcd56352kcescxoux3p6dbqdrghggyygnxa
108 cowsay.i2p q4ghzfpah4ffvm3bhc6fdkrznk5f6jxfjm2daytlparznai5d54q
109 crstrack.i2p mm3zx3besctrx6peq5wzzueil237jdgscuvn5ugwilxrwzyuajja
110 crypthost.i2p zywhrxtnkjc3rxxvxbocom7ml4hnutomgtuvqrwyf3rhuupnq5ca
111 crypto.i2p vffax5jzewwv6pfim55hvhqyynafkygdalvzoqd74lkib3hla3ta
112 cryptostorm.i2p mlu7mswyirjf53usqq7gyamvqc6rqihezgdbevov3dkxmkfo57aq
113 curiosity.i2p eomeif4xrykxlzhawc3icdilje5iammijos6tyizwhrfh3j7qdvq
114 cvs.i2p yd6k7dzpsa2tnlzx4q7xqkmd4qsjk5xk5hbiqpiarwbeyvxaxgba
115 danwin1210.i2p eoqdf4no5dxn4tw5n256kkd4lzz3uk4p47np4mepsykpsdzrnvba
116 darknetnow.i2p gkx3o5fy7mv7l4psqqnhp35d5iun7rt3soci6ylf3rgb7a5a655q
117 darknut.i2p 2mk37gtvpk2i63o6vl7vna4dr46rqexxetupgn5efuuins7x3qya
118 darkrealm.i2p gbh4eerxdsph7etxsxznfhvmuiz54trlkenakqep343u4xcoekzq
119 darrob.i2p hz2xhtpeo6btgiwi6od4qj2575ml5o2246rd5orarruyjhd63zja
120 dashninja.i2p dzjzoefy7fx57h5xkdknikvfv3ckbxu2bx5wryn6taud343g2jma
121 davidkra.i2p nq7ca2egm563nir3xegfv52ocgmxstpz56droji4jgnzfoosk45a
122 dcherukhin.i2p qa4boq364ndjdgow4kadycr5vvch7hofzblcqangh3nobzvyew7a
123 de-ebook-archiv.i2p 6mhurvyn6b6j6xa4a3wpuz7ovpsejbuncvyl6rnhepasfgdgmn7q
124 de-ebooks.i2p epqdyuuhtydkg5muwwq47n7jvr66pq4jheve7ky5euls6klzwuyq
125 dead.i2p 7ko27dxvicr2sezvykkrfiktlghx5y5onup3f2bas5ipocy6ibvq
126 deadgod.i2p 63bveyh7wefb44hlia7wtxxb3jal3r67thd6jekmwrtq4ulaaksa
127 debian-multimedia.i2p cylxxz2y35x6cvyrl57wu3brckurtexatyi2i5awz3eeamqwjspq
128 decadence.i2p pw5ys7k2grjb5myydpv6ohikm6nna7y6u2dro44i4rucgulu3ikq
129 deepwebradio.i2p 2nait2gdeozkgf6gyhzjfij6mwldwkxxwcvtxobb4b5q5cvtm5la
130 def2.i2p cepsrw27kdegwo7ihzouwvgcvw2obswwjs23ollgj7hk2yrce3da
131 def3.i2p xbf3ots2purqun7orn72ypkpjmrzbfrkj3u654zfe77hbrbow6la
132 def4.i2p yyzdq4fwwmnlojp23drfpfqujln2vcjozjrfzfeuriuqzdq7g4mq
133 deploy.i2p ujzspsqkbz5z272eozsrdv4ukl434h3fuliwrfxxnab74jmd7e6a
134 det.i2p y6d4fs3rpqrctuv77ltfajf5m4tl4kzcu7rtwhxgiohylfxxow4q
135 detonate.i2p nykapdsjjswdkjov7x3jzslhg4ig3cpkhmshxqzijuhbisx25jja
136 dev.i2p cfscxpnm3w3qxnlv3oikewxm4qrot4u6dwp52ec2iuo6m7xb5mna
137 di.i2p 3irnooyt5spqiem66upksabez4f3yyrvvjwkmwyzlbealg64mgxa
138 diasporg.i2p edvccoobtjukjgw2os5eetywanbb2mpag5aknkrpia5qx2koksua
139 diftracker.i2p m4mer767ipj7mq6l7gdrmrq37yzvsj3kzezd7n7nsfuctntjseka
140 dm.i2p heysbdivyeugdbggpscco5wje3dsvwgcpp5ot4sopooebnmiqvtq
141 docs.i2p ato242wckzs4eaawlr5matzxudt6t5enw73e4p6r3wajwkxsm3za
142 docs.i2p2.i2p las5l45ulwwf5i72nht6vk33sfkidcpr2okpf5b6mvgbk3a2ujna
143 downloads.legion.i2p xpmxdpuuptlekyhs7mmdwkvry7h2jbvpqpzsijqe3a5ctxgodesq
144 dox.i2p vk27cjdrtegfdnrjqutebgxkpyrfj42trdfbsupl5zn2kp34wb3a
145 dropbox.i2p omax2s5n4mzvymidpuxp2yqknf23asvu54uon6cxl6gdrlblnuiq
146 duck.i2p 3u2mqm3mvcyc27yliky3xnr4khpgfd4eeadhwwjneaqhj25a65ua
147 dumpteam.i2p 2fwlpuouwxlk2nj4xklvm43m52tqyhqnu2fcfiuv7clvf3wd5nwa
148 dust.i2p u6xgh6zhhhvdvefbqksfljfs3nyjvqcrmyamp5bryz5f4injmniq
149 dvdr-core.i2p fg6l2ej6qrk5rkyfzdptxx5xkcm4kvdla4gg2tun7z7fm5cxxw5q
150 dyad.i2p 7n2ljphvp2dep7imoujvydxp4myuxfld3axwfgcny5xc5x6jj6ka
151 e-reading.i2p z54dnry6rxtmzcg7e6y3qtsig5yf5fmehuvakcg5wnuahx3iafuq
152 easygpg2.i2p bwxry5alzx5ihgrd3glah4eotddblzhalvpheppnw4zcajzqoora
153 eboochka.i2p ou7g64d5in4sugv5fgmmzwnunuw5hloixio7puthmrvrkwrp6egq
154 ebooks.i2p bvpy6xf6ivyws6mshhqmdmr36pruh2hvoceznzeag52mpu647nzq
155 echelon.i2p afvtspvugtd32rsalxircjglh3fhcjzk7gxrm3gw4s2yrpvzk6wq
156 echo.baffled.i2p bfr3lyicr72psxvt2umqfb562rtex66w6q3hi3tktzkoyane2iha
157 eco.i2p 2dq2o5h6c6a674qaduipp55mid5iktumjbswuwmpsrcqaeowdvwa
158 eddysblog.i2p ieac3ub4g5sy3wuhsbqfembnpp7f3a37xgcx537ytzsmgfzexnbq
159 edge.i2p aknsl5wmzjmwyc4wxutfdwy2w5vgd3vcx52mqx647hcgvyurmqta
160 eepdot.i2p t6edyotbxmxvy56fofdvmragvsj65te2gkhvzv5qnblicutyvgoa
161 eepshare-project.i2p sn26kom4qyuzouppv4lwnk6bqabdydcegtrilybviibwiq2s4nfq
162 eepsites.i2p isskhl4ak3g7qevrarlmblddgr4ugnn3ckalwpjcvxafk5rjgypq
163 elf.i2p duz6ey27ohpcp3llylklzdb63lylolzcixad6bh7rt5tkq42qqpa
164 elgoog.i2p z6hrgkg2ajmuzlrddjlffrgctx7x7fkipm6c4hdzmohyn5wkr4ya
165 ems.i2p 734zw4jsegdf55zl3z6s22tqkbxcghu4qvk6q2wevjfmx7xhbn6q
166 epub-eepsite.i2p yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
167 es.hiddenanswers.i2p cw7ge5ey4ekp5iep2kaw6j54boebtqytpcbnvio2bfpccd5ejzfa
168 eschaton.i2p xe75f5hzmrq6rkhsef2geslmi2v2yfngdiysmlmxvh7b4pyyjk4q
169 esuwiki.i2p cwxuiwcpymb72vm5vluba66ofhugyf5qeevvwo7e2fqrxl243coa
170 evil.i2p ljfl7cujtmxfffcydq77pgkqfxhgbikbc6qxjgkvcpn4wzd73a4a
171 evilchat.i2p s5b7l3hzs3ea535vqc5qe2ufnutyxzd63ke5hdvnhz24ltp3pjla
172 evilgit.i2p mx5vyoqhg77yuhthwznsxrepjsemq4uwitx4lxdzetk36ryl5rla
173 exch.i2p vsyjsbbf2pyggtilpqwqnhgcc7mymjxblamarmxe5hmbxaxvcndq
174 exchange.gostcoin.i2p n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
175 exchanged.i2p ylmulgfskl6uiwac4hw4ecwqdzd3oxtwaemzj25zc6k5q4rkexra
176 exitpoint.i2p 5zmjurq3enudcenegnxu5hqmfmayz4lxvnik6ulch4xssa2ithta
177 exotrack.i2p blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva
178 explorer.gostcoin.i2p ktoacmumifddtqdw6ewns3szxths2hq2fat2o7xnwq4y3auga3za
179 fa.i2p 6n6p3aj6xqhevfojj36dixwbl4reopkhymxmatz7ai5sroh75rka
180 falafel.i2p djpn5cbcgmpumwcriuzqistbae66txca2j4apjd2xesfgb7r5zmq
181 false.i2p 77mpz4z6s4eenjexleclqb36uxvqjtztqikjfqa4sovojh6gwwha
182 false2.i2p j5i2tfumh3ti5sdtafwzzbpupmlcbg5drysfay2kxbdpsaljrosa
183 fantasy-worlds.i2p 62a4xcyyhvfrcq2bkckb7ia37fmrssrgx467tlkxp32fjpq577wq
184 fcp.entropy.i2p de6h6ti5z3mcbdcwucu45vplikqyoeddsu3rqy7s2zy5i47j3peq
185 fcp.i2p ndsznnipoeyapnsg3gj3yi2dzsqduxwalmujm5mzjm7e6x374tta
186 fedo.i2p zoamh7e3k2vf2g6pfy46ho4taujk2f4mxqqsv3gbg554fxbvyfqq
187 feedspace.i2p kvtnpx4jylgeyojfhix4x462sqn5uork3roml4sfzotkxx62i4wa
188 ferret.i2p kkqie5qmja7bkf3iad4zxhrdarwj7kbrx2m3etn5kmba3shgwj4q
189 fido.r4sas.i2p i522xmu63hfbaw2k54cthffcoqmeao6urjyq3jg4hddf6wf57p3q
190 fifi4all.i2p v2stz6bsot7sbjzix5tky5dm5ej7gidmjnkvzqjju5xvz5sz6fwa
191 files.hypercubus.i2p qfglq25jwieszgyt7muz6dambzqsrmjhhszygzzx2ttubc77sffa
192 files.i2p w2sy74xe6oqnuz6sfh5fhkzu7boholgzd5f3anhj47srxwpj2vaa
193 files.nickster.i2p yil7dp2hg5pbqyovsiwb2ig6zjsq4tize3fnwemmqdrr6j5itdtq
194 fillament.i2p udj2kiino4cylstsj4edpz2jsls77e32jvffn2a4knjn4222s2oq
195 firerabbit.i2p awqh7n3wskzl3epyvkdwgarmfybsncm7vye6psg4tpkmplh3mj2q
196 flibs.i2p ocdm33e3h5tdml3yyholj4objdwsrhlugfqjnqgdkslmgdzb6b3a
197 flibusta.i2p zmw2cyw2vj7f6obx3msmdvdepdhnw2ctc4okza2zjxlukkdfckhq
198 flipkick.i2p aso5rzc4ym6g2bcbxjy2n573bmbenkjawva2jg7fhyqhwtwgu6lq
199 flock.i2p hflpi33ko5bi2655lx6bpzstdnjqgzrz23inovqjx5zpntyzyb3q
200 floureszination.i2p vitpvfb25sikuk3crgcvtcdi7hajxnnq2t6weay3no7ulur2wwwq
201 forum.fr.i2p onvelkowkbuwrglhw2cnocggvbdudi75sll5mfirde3cbopjqivq
202 forum.i2p 33pebl3dijgihcdxxuxm27m3m4rgldi5didiqmjqjtg4q6fla6ya
203 forum.rus.i2p zd37rfivydhkiyvau27qxwzmerlzbqtthsa5ohtcww62zrygjaga
204 forums.i2p tmlxlzag7lmkgwf6g2msygby3qttxvm6ixlfkq6s6cpgwubp33ya
205 fproxy.i2p keknios3gm6kh6onez6x2bm2t7stv54oanvltuagphgdfjdw5e2a
206 fproxy.tino.i2p fpaituvuvyxp6xdjnv3i27alnj2ifzcvqdweqb6yj5uybotzvyha
207 fproxy2.i2p r4lgw4wmza25g7j5fjocjbwzwthfg4ymcbm52ref3hh2hogskcza
208 fr.i2p ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
209 freeciv.nightblade.i2p rluupsgxbvw5t7jno3apyzlrdirjkljft4gdoy4mxxh4fmd4xzta
210 freedomarchives.i2p 4ck6oliqfjz3sccpya2q4rh5xkj5xdxkqs76ieml37537nfhwd2q
211 freedomforum.i2p abzmusjcm3p3llj4z7b5kkkexpsxcnsylikokouk5txfim3evqua
212 freefallheavens.i2p giqnkltyugfmsb4ot5ywpvf3ievuswfurk6bjie4hxi2hh2axajq
213 freenet.eco.i2p 2kf7ovb35ztqkrurkm76y34jfpwi6go25xj7peznnmxrl7aieo7a
214 freshcoffee.i2p sscuukigp6alcb3ylhkcugoejjfw5jqgtqbsbafw4hyku42lgc3q
215 frooze.i2p m6ofa5dmyse4b4jg7kfmluuuc4pw5jqu6zh4qnboin4vropxepja
216 frosk.i2p 63naq7zb3hvbcppj2ng7qwf6ztusp4kwpyrzbt4ptafcdbu4pfjq
217 frostmirror.i2p ycz3imuz6yte2zhlapmsm3bsvc46senvc2jxzwsbfdct5c72qulq
218 fs.i2p ah4r4vzunzfa67atljlbrdgtg3zak5esh7ablpm6xno6fhqij35q
219 fsoc.i2p vaqc4jm2trq7lx2kkglve7rkzxhhaptcwwl32uicx4ehf5k3hx6q
220 galen.i2p 4weo7zkxscxbcouiqx4mlnb35uwl2lromikzk33er3fljktyvi2q
221 gaming.i2p rfxberwod6st2zc6gblqswxjl57nucgc3xrbwss43pe3dvqqzj4q
222 garden.i2p qkk2dqx6nocycgt3vinsoc76cxkb4jreybcpgz3fcps2dbe4rowq
223 gaytorrents.i2p fnggbr2t2aulr6rvlo4aehotx6wecfob7u3k2nxsnvtm4xex424q
224 general.i2p 5fklrsztdqpl3hkkwwrrw2rdowrq7wwhwb6h7avvk4fhansp4vvq
225 gernika.i2p wpzqv3lxpecdsvcaadvbmrhhwlc7kp4n2mijdv2qjw3zr3ye232a
226 ginnegappen.i2p kbhfkzx5jeqhfgss4xixnf4cb3jpuo432l3hxc32feelcmnr3yja
227 git-ssh.crypthost.i2p llcp7jvz3hgtt3yzkdgjolwobisgvhv4xqa5a4oddejllyozur5a
228 git.crypthost.i2p 7frihhdcisdcyrzdbax6jzvx5gvtgwsm7m6kcem2tlaw4jtahbqa
229 git.psi.i2p em763732l4b7b7zhaolctpt6wewwr7zw3nsxfchr6qmceizzmgpa
230 git.repo.i2p vsd2vtgtuua2vwqsal2mpmxm2b2cpn3qzmqjoeumrrw2p4aot7uq
231 git.volatile.i2p gwqdodo2stgwgwusekxpkh3hbtph5jjc3kovmov2e2fbfdxg3woq
232 glog.i2p ciaqmqmd2wnws3hcpyboqymauyz4dbwmkb3gm2eckklgvdca4rgq
233 gloinsblog.i2p zqazjq6ttjtbf2psrtmmjthjeuxaubi742ujrk2eptcsaoam4k7a
234 go.i2p ll6q4lsirhwkln4dqxwqkh2xu4mu3jiy546b4uhe4fypyb4vvx2q
235 gonzo2000.i2p nogsv7okydhbvrewv6hb4xdojncvhkusnyib4lglluc4uw67a37a
236 google.i2p 4p3ajq4cotnflmuv7fhef3ptop5qpm3uzzgp5bahxif3nc4w3ffq
237 gostcoin.i2p 4gzcllfxktrqzv3uys5k4vgkzbth4gqednwhfpt755yivm3davuq
238 gott.i2p dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
239 greenflog.i2p zny5ftmhzxulxzyczmeat53qjnue2xtqv2clisc7dg76lwfceecq
240 gstbtc.i2p n33uthzyqsbozl2qh5zii2bq2nnvbz6g6c4ew3mwp6uukk6u7wva
241 gusion.i2p 4qyfdhizjixe2psu7wcvqufix5wlijocehpb2futurcmlhlktrta
242 guttersnipe.i2p kizkhzes2bzp45widihremo6geepfk7dl6juourkvzuvlc6y3spq
243 hack8.i2p un63fgjgi3auvi7zscznwqfol7ka4johgthvqf635mg3fefsjgpq
244 hagen.i2p e2t6rqd2ysbvs53t5nnaf7drllkgk6kfriq3lfuz6mip6xfg644q
245 heisenberg.i2p jz4quyw7zt63tmw65jfp76fblwadjss4iyi4puqdg3dye7oaqlvq
246 heligoland.i2p gzrjm62ektpqjfsem3r3kwvg6zpjvvhvpjvwfxkm2ay4zu7sp6oq
247 hidden.i2p iqodhhqo473qv5gwhjcs2bsrbhlqtpzgpnuumpastfiyhuwb2kyq
248 hiddenanswers.i2p kj2kbzt27naifij4ki6bklsa2qfewxnkzbkgvximr4ecm7y4ojdq
249 hiddenbooru.i2p zma5du344hy2ip5xcu6xmt4c7dgibnlv5jm4c2fre5nxv44sln3q
250 hiddenchan.i2p 6y4tltjdgqwfdcz6tqwc7dxhhuradop2vejatisu64nwjzh5tuwa
251 hiddengate.i2p rvblcu54jvkkfffp3fobhunsvpgfc6546crcgzielzwe2s5m5hbq
252 home.duck.i2p jsh7yfvm2t5urdcnmfzdy4n6vegqskdtlwem53chgxli4ipfmuma
253 hopekiller.i2p kcaelbgsvrkiwpx36b4wxofebrl3njx7rgm5amzfmqwbomt44cxa
254 hotline.i2p 6cczi27iuxkm3aivazaemzltdqgh42ljzurqp43uclbz2lid2uqq
255 hq.postman.i2p 27ivgyi2xhbwjyqmnx3ufjvc2slg6mv7767hxct74cfwzksjemaq
256 http.entropy.i2p ytu7kz5bdoc26nkpw2hajwt3q7n5rcbg2eokyefhmkxmmslimbdq
257 human.i2p nrtcelq3humyfvoxmzmngpka6tmyifweouku5mbi5av4lc43hzaa
258 i2host.i2p awdf3nnmxxup5q2i6dobhozgcbir7fxpccejwruqcde2ptld443q
259 i2jump.i2p 633kqgmwzzu6vhkevwvbf2pfyejt3gkes34i6upa4og57fgdfcxa
260 i2p-bt.postman.i2p jeudwnx7mekjcowpqo6xpkwn7263c57y5piurrjrdzinjziu4fla
261 i2p-epub-eepsite.i2p yxvzjwd4vin6pnjauekdufh7lxaijal3kqe2bhakuf47g5zkb6xa
262 i2p-javadocs.i2p icgmr6hhjudl4yxhtuq4pxvss2pzypwddzowajgs5rdz6f55novq
263 i2p-projekt.i2p udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna
264 i2pbote.i2p tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a
265 i2pbuggenie.i2p bioq5jbcnfopqwvk7qssaxcl7avzeta6mu72jmxjeowflpcrhf6q
266 i2pchan.i2p tduxyvfs7fzi26znvph3mu2d2ewaess7emomfci22wvownajphuq
267 i2pd.i2p 4bpcp4fmvyr46vb4kqjvtxlst6puz4r3dld24umooiy5mesxzspa
268 i2pdocs.str4d.i2p yfvbtrhjac3jutdsqzugog6mbz3jtyhpwovrt2mqc5mzv534y7cq
269 i2peek-a-boo.i2p qgv64klyy4tgk4ranaznet5sjgi7ccsrawtjx3j5tvekvvfl67aa
270 i2pforum.i2p tmipbl5d7ctnz3cib4yd2yivlrssrtpmuuzyqdpqkelzmnqllhda
271 i2pjump.i2p 2mwcgdjvfvd3xwumzqzqntual3l57h3zo7lwdmkjboeraudpkyka
272 i2plugins.i2p bb63kmnmbpitsdu45ez54kmogvvljn3yudksurcxiyq7dn5abt7a
273 i2pmetrics.i2p v65p4czypwxrn35zlrfkar2w77vr42acd7gbszegsrqq4u7sip5a
274 i2pnews.i2p tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq
275 i2podisy.i2p 3c2jzypzjpxuq2ncr3wn3swn5d4isxlulqgccb6oq5f6zylcrvcq
276 i2push.i2p mabdiml4busx53hjh4el5wlyn4go5mgji2dxsfyelagi4v5mzjxq
277 i2pwiki.i2p nrbnshsndzb6homcipymkkngngw4s6twediqottzqdfyvrvjw3pq
278 iamevil.i2p au7jhslyt4cxkjp365bvqvend3hhykrrhbohtjqlgoqrlijbezja
279 icu812.i2p bxgqwfsnr3bgnr6adn62anjcin5nuthqglotb3wn3dgynsfofeva
280 id3nt.i2p ufuqdzsxltiz224vq5gnuslt3a3t72dhy5kq6i2xway53m6pzv6q
281 identiguy.i2p 3mzmrus2oron5fxptw7hw2puho3bnqmw2hqy7nw64dsrrjwdilva
282 ilcosmista.i2p 6u2rfuq3cyeb7ytjzjxgbfa73ipzpzen5wx3tihyast2f2oeo24q
283 ilita.i2p isxls447iuumsb35pq5r3di6xrxr2igugvshqwhi5hj5gvhwvqba
284 illuminati.i2p syi6jakreatlm2z22u76izyqvbm4yi4yj7hr7jb63lgru5yhwwla
285 imhotep.i2p qegmmhy52bdes2wqot4kfyqyg7xnxm5jzbafdb42rfoafadj2q7a
286 in.i2p r5vbv2akbp6txy5amkftia757klgdy44s6cglqhmstpg65xycyjq
287 infosecurity.i2p v3gkh5kqzawn2l3uzhw6xnszsh6w3nztjmlwil7p4kyrwrsm2dba
288 infoserver.i2p jd3agbakybnhfvkeoxrx7t33iln6suzomv3kxkxf77j7rkonch6q
289 inproxy.tino.i2p ex5yf6eqqmjkrzxnkn6cgvefgne24qxsskqnpmarmajoit43pgma
290 inr.i2p joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq
291 instantexchange.i2p 5wiyndm44bysev22kxvczxt37p6o6qroiqykytrvn2yzi55aqfxq
292 investigaciones.i2p n7hqd4asxrdwf3zwo7rzv27y2qkcfmakmz6mjar6aw6hlc4c7mha
293 invisible-internet.i2p jnpykdpp46zenz4p64eb3opadl5g42dls3rurk2cvq6a3g3rvbvq
294 io.i2p tx22i6crnorzuti3x6va4mijsbhoqswy2cfdxjbvprgsq4eerg7q
295 irc.00.i2p bvcja52pppgfspp2ueuipoysjnvvoyblz2h6smpxcmanjquogirq
296 irc.arcturus.i2p 5nywlbn35p2nwsymwpfmicu6fxono6g64vwusxbsvmm2qwz6vupq
297 irc.baffled.i2p 5zmtoopscym6qagkvpgyn7jnkp6dwnfai745xevkxlou77c2fsjq
298 irc.carambar.i2p hxzbpivxqxy6nuae4t6fnkhcgnhs4c72vt6mmsqfmfhrkn2ca6gq
299 irc.cerapadus.i2p e4ckznxcxvgyikzjmjsu72i2dbj2d76ogexyukklbjvpcnhp6zzq
300 irc.dg.i2p fvp3pkcw4uvijqabwtekcdilklp73gyasuek67wdcs2mucep4caq
301 irc.duck.i2p chdpmm4gxffyn24xx5dhxvfd5httu42i5gtoe6cctjlsf4mbofeq
302 irc.echelon.i2p ez2czsvej5p3z5bquue5q3thujcodfze7ptybctqhnqc7hms5uzq
303 irc.freshcoffee.i2p ubiu2ehtfnrleemgpzsqkahwnvzuaifqa3u4wmaz5maaisd5ycfa
304 irc.i2p l3ohmm4ccxvyuxuajeaddiptci5lsrnxtvtyq7iohphrt3oj2evq
305 irc.ilita.i2p 5xeoyfvtddmo5k3kxzv7b3d5risil6333ntqrr3yvx3yubz5tk3a
306 irc.ircbnc.i2p 4rqcsqd7xif6r4v55blqvmqu5er6due4eyene3mjorfkts4o3rxa
307 irc.killyourtv.i2p wre4majmg2vnbi6id27et7yw6lnpf56wkbm6ftnlwpvxnktq73hq
308 irc.nickster.i2p dhq3fhd5scw3jqhj5ge7kqfpprfolcgxfjbaw24obohaiqjtdu7a
309 irc.orz.i2p 7gifacog4aoons3syybojbbnyqqaaqijhngrehn2xlq3eucuyjcq
310 irc.postman.i2p mpvr7qmek2yz2ekegp5rur573z7e77vp3xqt2lfbco5i6nkfppcq
311 irc.r4sas.i2p hodhusp73gltozgrnianlbploon3rrvhrzfn5mf2g46o7aaau5la
312 ircssl.cerapadus.i2p 4x2i745i4w52ss3he2kse6tzwt64pr62yvrcb72lgvrb63fup6ea
313 irongeeks.i2p ecduxoion5uc5hnvzjxff6iiwhdwph6gse3dknyvlo7e6gaeho7a
314 iscofsi.i2p enjgdxs4um2dmhdb2ajff2egrdijkjji3g47m6unb74swbrqsddq
315 isotoxin.i2p wue3ycaccf4texikza3fh6p5yrmtgnooisuypnepo5mo67lmpcqq
316 itemname.i2p o35ut7hgywy35okvgkjkv3ufzv2ejv4luap4oytwbyy2jqy6u4vq
317 ivorytower.i2p fpwrfvidfexsz7dspofkwtkmmizm7lyralfz5kvykffk7gubvxsq
318 j.i2p kjxvohlsf5sdrzxzfcrmvquccnoevi6ytbl63mstsru5wt2dx3ea
319 jabber-2.i2p pvnmzgemetkwcuvt45omgowmeznwk5xw3nc3ygeoz7yekqxy57na
320 jabber.duck.i2p rhdzvvzraqzzm67zpyegb7knpfrjeffitixqzeyymdoz56uh2rtq
321 jake.i2p v2axvy6pqefnla7gun5fmqs4lqe4xfyqovgzcundhxrpcdvfd7cq
322 jar.i2p 2fthkmujup3xiiu3yple24n6g4emzdiiimbuqwvpdddtsr3c4nrq
323 jazzy.i2p ha5c3zafwkt6mwqwjcf4oqwvbwz473652ljjadiwrj4gfkfkjofa
324 jdot.i2p kw4jr5qw4bhnj33avkwankjdh3zi7wtahlmgkjwvsv2isskkzgpq
325 jhor.i2p c6rnm7oemydhuwzmhwwwxphkzanez5rnn7fkcs3lpgu6gkgtssoa
326 jikx.i2p aazr55itvyns4lwppvx5njyx5tjdwemw4w6jbmpegdunznod2ieq
327 jisko.i2p jxgfvr663uhr6m65hrgkscshysfshkq32ywdubc4ed7zda3e2pca
328 jmg.i2p oglpnq7zungdukmk6gk5fzj5jp6wibuoihqgks453wztrwos4ggq
329 jnymo.i2p nbfplxgykyfutyadlfko2rmizdsxox2pee2ahboj5mju4s3putda
330 jrandom.dev.i2p htynimemonyzqmn76gworxyfkmqtsa7zcprbrd3i5cxqqm75tuzq
331 jrandom.i2p dqows7dpftxxl2bd4bgcpkck6knrysdun6mtqy4ms5dxobbvg3ja
332 jrrecology.i2p qxi24gpbum3w3kesuxvheyu3p5u5o6tuvoypaolub2gnvbld57xq
333 jwebcache.i2p xdffxnxtjd6ji2zig3cgva7igvl2tiapyjoc7ylbzwqhxudbmvfa
334 k1773r.i2p zam7u6vslhemddz347uusuzjdk5wma4h5hcmcqlng4ybbpdbjhnq
335 kaji.i2p z5ic7gvm2k4doczphtrnrspl2w5sfbss2de4z3ihjijhtjw67ydq
336 kaji2.i2p 4lscgc6napekfx7ay5fdcjofeja4fnl7tqcd3fek63t4saavur2a
337 keys.echelon.i2p mwfpkdmjur5ytq4og36ym3ychinv36b2a57f4rmgqmtrwepq3fva
338 keys.i2p 6qv4x7ltaxckd4vbay5s4ntqqflq4efk6oke2d5yzicqrmk443ba
339 keyserver.sigterm.i2p isoxvnflrdn7cm76yjlfg5tbcugoito2hur7eidbqmo33xmwz5ga
340 killyourtv.i2p aululz24ugumppq56jsaw3d7mkbmcgo7dl2lgeanvpniyk2cbrda
341 knijka.i2p knjkodsakcxihwk5w5new76hibywia5zqcgoqgjttzsausnd22oa
342 knotwork.i2p 2yocdbcjiyfaqgxb4l6oenrrrrie6nydgmbnbfulqg7cik6bozxq
343 kohaar.i2p qchpjehbhqjbxdo7w3m55jbkrtsneb7oqoxcr24qttiq6j5g3z5q
344 krabs.i2p 3yamyk5bgfgovg6zpvtvpdjk37ivjj2wog2w7wha5agzgxxkqaca
345 kuroneko.i2p wbit2huhhwlyqp2j4undccuyrodh6qcmzdeyuaoy5o4ym7g5gdgq
346 kycklingar.i2p gctswdhp4447yibxfbqg3uq2bvx63qjeqnaoaux75zw73leakyva
347 lazyguy.i2p ia6xlsnygorllplx2owokahtrkospukvsmysz7i7bzw3vejc4hdq
348 legion.i2p 5oirascyhwfy2tr2horw6mixozsre7z6s7jfq7qbnj523q3bkebq
349 legwork.i2p cuss2sgthm5wfipnnztrjdvtaczb22hnmr2ohnaqqqz3jf6ubf3a
350 lenta.i2p nevfjzoo3eeef3lbj2nqsuwj5qh3veiztiw6gzeu2eokcowns3ra
351 libertor.i2p 7gajvk4dnnob6wlkoo2zcws7nor3gunvoi7ofalcps5lc76wruuq
352 library.i2p brqqaq44vbeagesj5o3sxcnkc5yivkwouafyxa77ciu7l644ei2a
353 lifebox.i2p pyqjnycm55cuxow22voqj62qysrjdnb6nbyladaiaiirqi7vp2yq
354 linuxagent.i2p ap5riaikrjq2uv5qvy7klzhhqywvqi7wqscyipsewcun7w2eynlq
355 lists.i2p2.i2p vmfwbic2brek2ez223j6fc6bl5mmouzqvbsch45msvyyzih3iqua
356 lm.i2p yeyar743vuwmm6fpgf3x6bzmj7fxb5uxhuoxx4ea76wqssdi4f3q
357 lodikon.i2p u3f67staiwhqxpacya3clmvurdwd2kp7qcthzhstqnhrmlwc2g4a
358 lolicatgirls.i2p a4lzmjyba7aq7hl6okqpds7znnwymolqnr7xhvno2wraqb7uhfla
359 lolifox.i2p 7fd2clkiotjnaoeigdtxlkkb24eik675ovezjf67x26ysham4zca
360 longhorn.i2p pohcihzxzttjclrazhs3p76wt3ih737egb5bovqb6ym3du6z3o7a
361 lp.i2p jiklbujn3cbfikf4pca526jgmorx6mxhil3twqmfoteaplx6ddwq
362 lucky.i2p wx36m3wnpt2y6bngdpg3ifrarvtkpwnluarx377bllpgvkuhybaa
363 luckypunk.i2p y4t6cujjxnnrtln3rgmfbgbh46hic7wkef57krd7opitbgngohka
364 lunokhod.i2p 3yc6sp7xic4grmpfecbwuij6z3dp5kdgoo362pszaco7io42mnwa
365 m16.i2p ucsr3eveuc4mx5y6gxnoaywd4ojvbel5q3ynns6s5yfw3vusmfva
366 mac7.i2p 3yjowssqzydciwa5zx55kazgf7q7w6g7rkocr7bngy35ii44t34q
367 madman2003.i2p a2sam2xbhxbzmeyobphbxrkdwlppoerewq5qvibbyk3ftsr643qq
368 magix.i2p cgfnyxv62msfynsfbv3kju22j2mt6tfnopshhmrcmpcrxyts6xwq
369 magnets.i2p snz46nez6hrrpg6336neinflw56l3vwatk6bzzytwu77xmsfsoca
370 manas.i2p 6qolj62ikkoq6wdn3hbvcbdmlvf2rcyv432kgi5uy7mvrczmjtba
371 manveru.i2p pbmbofs76wpjnxi55eqtwg4y6ltyij72o4fm4sxfjol3y57ze5sq
372 marcos.i2p vpo36bsil2voqaou53zshuegssqaroa5mbrzxfmhjywlbojckalq
373 marshmallow.i2p svdqd6j3y3gwryufcl4fkzpmcujgvrvphvk2oy4r7m75xs327e2q
374 marxists.i2p lepah55qyp2fhuwxlz7bwrhzckn4gkuofivnofoeuyfpmke5x2hq
375 mattermost.i2p x5oovnhnuli5fnwtgkbd5z5jvrvdvprqyuofywx6uoxkk4bie6ya
376 me.i2p dbpegthe42sx2yendpesxgispuohjixm4bds7ts5gjxzni5nu6na
377 meeh.i2p 4oes3rlgrpbkmzv4lqcfili23h3cvpwslqcfjlk6vvguxyggspwa
378 mesh.firerabbit.i2p 3x5wokr4bjy5z3ynji4fyhvwzv4fvgry3xafi5df5h75doezjytq
379 messageinabottle.i2p avfhe3kvrrv7utxn2vre65lg7damxzzsewq3vukwie4llitd254a
380 metrics.i2p z45ieamhex2ihqv7oowk5fz4qq47rbvxhhhbaaiinpajbhuevtpq
381 mhatta.i2p o4rsxdeepfrnncsnjq675xogp5v5qkbfgbt6ooqeyfvlifobrjxq
382 microbleu.i2p mtapervgibruizniems2yyr47pin2wpysyh7m632rigl26vjc6qa
383 microsoft.i2p hvaqr5idszdyrjph34amb4mjosqd3ynggoxlnj7ciqhnx7q6plza
384 mindisl0st.i2p u7rnqhvsuyxd3fabm4kyzn7brgz3i3cporj2emk2jmbpcmltyf7a
385 mindspore.i2p uuh5dd3y2rqa7x2jpggm4p2pg6znarm5uanwsvybe4tk36ymwr4q
386 modulus.i2p ctz3o6hdefrzwt3hlg6rjhdcbjk6irppbndq32u6jnn4lz72f62a
387 monerotools.i2p 5bal7dngxde2ddmhuzbtfken6w5nmxmixtjlrlmxt3wbhnemv73q
388 monerujo.i2p puri6y5dtwh6zr4u77ep6ozatun6iz7v4wai2dzxppz7654corlq
389 morph.i2p iovyp2dao5rta6g5v6hke2s4ugx2btkpcljddak2yhxfrx3l4dqa
390 mosbot.i2p 5bhmrp43mjwlzf4x64xgdrkwmw4luvng6eq5waa663a7vnkp732a
391 mosfet.i2p s5ynkgagndmpxpf2kmnenv4x72io664gzd2x3qef54ilammnte3q
392 moxonom.i2p gcjdrvnlobgexh7ebv276pwmnoj3yoyaqm3w4vmmdha4lgxfinqq
393 mp3.aum.i2p n7bmu5dwux7f6gedmdik6zrm77bnls4lkzo2vo3bf4bwegk7vkjq
394 mp3.tc.i2p w3ied5s7ldjcvnhxu2gyofe3oogzbplkyxshzfkhspiy2526snsa
395 mpaa.i2p m6cqnglo7xlytwxkdsmwf3d23d6lq5r446c3tktb2tdmuah36zya
396 mrbamboo.i2p tmpmkx6wlbbrgsnexrqlrib7laoegpbfeop7bnyezegii7hecpxa
397 mrflibble.i2p u7k2qcmkrril6yvudvwxjqz7k3dzgp3jdejjjeapej7liselj3eq
398 mrplod.i2p fjn5hxtybxyfyvdf6u5v5seg2sjd47hb5by6sa6ais4w3xnrxwyq
399 mtn.i2p xisk3h6sku3iqj52uriogaajmnku7pwjux7wa4omx2zloamuw6eq
400 mtn.i2p-projekt.i2p f52x5fp6uhq53f5zle5d6rq5un34xgmxgazvilvmzcby37xcmsfa
401 mtn.i2p2.i2p l6kuhtmgvbp57d7jwalj5nksi6nr4gfzbz4oit62lxgipb3llt5a
402 mtn.meeh.i2p h7ylrsuzzynrxp3jql7anoozyqblavj7eqces6o3wngvuuxhs2la
403 mudgaard.i2p yz32lk42gtoesknesfolq3tt4erxxcejcote5pontaeqev3bj2kq
404 mush.zeit.i2p dk3sg23kljawxqp3cb6xz5mnzjlyckzvq5jhqs5gnvdsv7wqn6ha
405 music.i2p akamh76yi6p7xxbvl3qv3yhaockne57yfuh77acogbgpjmwypvia
406 mysterious.i2p p66g2a4nzfkvidd3l7nwphcnfa3ttyu5kiolcb4czec2rn2kvwsq
407 mywastedlife.i2p ceumy3puvvsrru5bmfmtgsajsx5qyehqac7l7a23xpwtfs2bvcgq
408 nacl.i2p bm2fib3tumer72lopjh4nmqomwvqu2sdfyb2hmr6lnk7jbw3vvia
409 nano.i2p ex5ssv7s3hj6jp7hvadxfw3wvbjbvnczxr4pbk7qw26ihiorjmba
410 nassai.i2p v653cocvn3i6bgjdm3ciwbdnu32supglv6gn4fh23bohemsp545q
411 neodome.i2p 5hkhjehj3ct2pvcah7dcylwef2oti3xij5myxbv3pd7rocio5vkq
412 news-i2pn.i2p wwcqkwfo5yhe6uribv5tzylk25j5hkdk6gdnyftzd3k7dawlzwca
413 news.neodome.i2p trhwcnygfkeqjj6g4xhmrdp4gsjqsye47lsxshbmwbten4ywt5oq
414 news.underscore.i2p rl7t3kspoktuatjcu7gf7xleu7y6biibs4fspzo24kll6n7hbq4q
415 newsbyte.i2p gsk3rgsejxxrfabjxu5w5plplxsu47aoeoke22vvhlwwllzosnxq
416 nibble.i2p jmdxcpdzqafedn3clc4y7u6o56qocfiffrzbzncmtggqtio5qjpa
417 nic.i2p vzu5ymab6klevpcdudv4ypisjqaznmt44e6lcg7dwiuza4saibxq
418 nickster.i2p zkwsa6kvq2wdhovw5g5wqakpb7rlaylyhfriwmurots5pvwbqauq
419 nickster2.i2p eofzi7npzpk4p5gb4qper4hmwgxo6kepo3dheeblakewedxj2bwq
420 nickyb.i2p gmpxk4tje7mnud32kg2kjmf36f6cpwqakzc2dxuzjnnz4qr5w4sa
421 nightblade.i2p p4gkon7ytswxrbwkl7vruw6mg7kfw5aofovqjgt4c7tnqmbq6lha
422 ninja.i2p q6dg6hlb3egzdqz352ri5rc4fx4gcrdeu3tpiyfxlv73yfjgrhya
423 nm.i2p 3itdpqzyn3ii7sivppo4sxxwhvgtpskzkbokrdibim6gqpvlw5ya
424 nntp.baffled.i2p kc6muo2tih5mttbpzecteegvtonuysjidk3emcy4cm4yifzild2a
425 nntp.duck.i2p gvzzor4utsqxswvf6jaglfks7yxudlz2s326ftrk56i4lpd2s47q
426 nntp.fr.i2p npoztnqadfnu4vrokoh6rusoi3yne47s6jurc3lzhcrzzia5eqva
427 nntp.i2p wwdzmeyler4djegvyt2bxmkwrckfgg3epkkwowyb75s47he6df6q
428 no.i2p lpsg4x4gdrf7antxcdy47cl6abcqei5ommgzt55retq7go5ku3ba
429 noname56.i2p oiyoslismzyxuw7ehxoigmtkdj35idim6flmlplddxuiiif6msfa
430 nop.i2p ssag45lathm4gqp46si7c4w4tioyvjpcza5uvz5x2zuljnplylca
431 normal.i2p j5fex634r2altzb3kjvu35qekt2r3hgsqzg5qxoy7dp53heu5pma
432 normanabcd.i2p si2vh43gvxjnw2shwr24j76xyanow4oa6gbu4idookbraoxl3s3a
433 nothingburger.i2p tesfpn757ysc7nih7mxher2b3jstkc3l5fhfcyb5kxhzhvv52trq
434 nothingspecial.i2p wzrwqrp52bilqijrlboclynuev4kzpjzfzlvzl5aqxqt5fdnpbga
435 novospice.i2p ukqap24nwac4gns77s4zy7j5cagt7l7syb5zo7eukfg3zn5gg5qq
436 nsa.i2p nsetvbclpomqxfcit4mghn6z7vdhnza6jdzczby4crnto32uykga
437 nvspc.i2p anlncoi2fzbsadbujidqmtji7hshfw3nrkqvbgdleepbxx3d5xra
438 nxt-wallet.i2p 33pp74k4ivy67z332qpyl3qlcqmi6gxqumrow4bldkblxxlxqq5a
439 obmen.i2p vodkv54jaetjw7q2t2iethc4cbi4gjdrmw2ovfmr43mcybt7ekxa
440 obscuratus.i2p i4j37hcmfssokfb6w3npup77v6v4awdxzxa65ranu34urjs4cota
441 ogg.aum.i2p wchgsx6d6p3czloeqvna2db5jr7odw4v4kqrn4gr4qiipfyrbh5q
442 ogg.baffled.i2p tfbvj2xal6lcuxv3hzuw7cw4g3whguombcv2zuotzvul4qtrimgq
443 ol.i2p bnb46culzbssz6aipcjkuytanflz6dtndyhmlaxn3pfiv6zqrohq
444 onboard.i2p qwlgxrmv62mhdu6bgkh4ufnxowxsatfb6tbs2zr666qyunwqnecq
445 onelon.i2p irkvgdnlc6tidoqomre4qr7q4w4qcjfyvbovatgyolk6d4uvcyha
446 onhere.i2p vwjowg5exhxxsmt4uhjeumuecf5tvticndq2qilfnhzrdumcnuva
447 oniichan.i2p nnkikjorplul4dlytwfovkne66lwo7ln26xzuq33isvixw3wu3yq
448 onionforum.i2p yadam2bp6hccgy7uvcigf5cabknovj5hrplcqxnufcu4ey33pu5q
449 ooo.i2p iqp5wt326fyai5jajsa3vkkk5uk56ofn4anocgpe5iwlpisq6l7a
450 opal.i2p li5kue3hfaqhhvaoxiw2ollhhkw765myhwcijgock5rs4erdqdaa
451 open4you.i2p ice6ax5qrzwfwzsy64bctffj6zlzpuzdr5np65zsxlbt7hztyc6a
452 opendiftracker.i2p bikpeyxci4zuyy36eau5ycw665dplun4yxamn7vmsastejdqtfoq
453 openforums.i2p lho7cvuuzddql24utu7x6mzfsdmxqq7virxp5bcqsxzry2vmwj5q
454 opentracker.dg2.i2p w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa
455 orion.i2p 5vntdqqckjex274sma3uqckwqep2czxs5zew25zlntwoofxk3sga
456 orz.i2p oxomqkekybmyk6befjlouesit5mhstonzvzd2xnvsk7i6uyrqsfq
457 os3.i2p s7x4ww5osrrfein3xgwyq67wnk6lgliw4mzt7shtu66wrb2zdojq
458 osiristomb.i2p t3slf77axkv3qm7c3gzpv3jgmkraoqqe2bojr6h66eipibofsyzq
459 ot.knotwork.i2p cxhvvfkbp2qbv5qojph7zb46molpe2ffanghnerjag3xdmy6ltxq
460 outproxy-tor.meeh.i2p 77igjr2pbg73ox5ngqy5ohzvrnur3ezqcogtl4vpuqtrcl3irsqq
461 outproxy.h2ik.i2p nwgvfpfarpnyjjl4pwsxr2zdsppcx5we3kos2vlwicbiukopgaza
462 outproxyng.h2ik.i2p v32zse2zczzgegelwxbx7n5i2lm2xhh2avltg76h6fz5tb53sfxq
463 overchan.oniichan.i2p g7c54d4b7yva4ktpbaabqeu2yx6axalh4gevb44afpbwm23xuuya
464 p4bl0.i2p lkgdfm4w6e2kkjhcdzr4ahhz26s3aunhrn6t2or436o73qh4z7ga
465 pants.i2p xez3clscjfafkqwk6f473ccp3yvac4kh6rdp6dptwxa2lhixizgq
466 papel.i2p mxskjqntn2d34q4ovsnd5mud7cgde734tdjldd3lt4hczh2645zq
467 pasta-nojs.i2p dkkl3ab6iovxfqnp44wsjgqaabznvu7u3hugpzyagbeqlxgvx3la
468 paste.crypthost.i2p 2zaj4u4s4l3lgas2h5p6c6pvzr2dckylkrh5ngabursj4oh25ozq
469 paste.i2p2.i2p b2gizskfea4sjxlw6ru2tb6kdrj47dsjc77cijsf5mzh4ogbmfvq
470 paste.r4sas.i2p csen43keji3qiw6uobsgzysxyjd225g6446ylq5uuz6ur2glkzaa
471 pastebin.i2p mnicncxrg2qqi55qftigiitaheugnj4rpysbk7zabdrirgktelqa
472 pastethis.i2p erkqiwnjl7vtysqd3wvddv6tfvnhswarqkbn4blhdlhfxn7cf2ha
473 pdforge.i2p wzeg3ehf6d2mqjqji3sd3rns776thvhe2vam2r6gjlmsqis2dctq
474 perv.i2p f3k3wm4ae7t7ottfjd4hu6is7zsls73izl2gm2qynzficxcdsiwq
475 pgp.duck.i2p wujajyxj3cgsfsbtr3g7g7npv5ft3de6pcstxlav26zq6cxdjmha
476 pharos.i2p vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
477 pharoz.i2p vathk2pyvaskeie63yyg4tshjkx5xt6zfvhwhgr3de67q46ob3sa
478 phonebooth.i2p noxia7rv6uvamoy2fkcgyj4ssjpdt4io6lzgx6jl6wujpufxedrq
479 photo.i2p fqhuy77ugd5htnubzkyy5guvwboqn6goahtmn2g7feewvdj7k3iq
480 piespy.i2p vzusfjzcu5ntnvobcvyzc4dcu4j6ommtnpmba2puk3kexgdzrl7a
481 pisekot.i2p 7yzdwhy723fodqz4onp6k3nyvixra2sa6dl45tcblhmyoa7i36nq
482 pizdabol.i2p 5vik2232yfwyltuwzq7ht2yocla46q76ioacin2bfofgy63hz6wa
483 planet.i2p y45f23mb2apgywmftrjmfg35oynzfwjed7rxs2mh76pbdeh4fatq
484 plugins.i2p wwgtflbaa7od2fxbw4u7q7uugmdclxf56alddvizugwcz5edjgia
485 polecat.i2p het5jrdn35nhkanxmom5mjyggyvmn2wdj2agyqlrv4mhzhtmavwq
486 politguy.i2p 6dkkh3wnlwlr6k7wnlp4dbtf7pebjrph5afra2vqgfjnbihdglkq
487 pomoyka.i2p omt56v4jxa4hurbwk44vqbbcwn3eavuynyc24c25cy7grucjh24q
488 pool.gostcoin.i2p m4f4k3eeaj7otbc254ccj7d5hivguqgnohwelkibr4ddk43qhywa
489 pop.mail.i2p bup6pmac7adgzkb5r6eknk2juczkxigolkwqkbmenawkes5s5qfq
490 pop.postman.i2p ipkiowj7x4yjj7jc35yay3c6gauynkkl64gzzyxra3wmyhtfxlya
491 pravtor.i2p 2sr27o5x2v2pyqro7wl5nl6krrsbizwrzsky5y7pkohwh24gn6xq
492 pris.i2p ahiwycgzuutdxvfqu3wseqffdnhy675nes57s4it2uysy5pxmz6a
493 project-future.i2p ivqynpfwxzl746gxf376lxqvgktql2lqshzwnwjk2twut6xq7xta
494 projectmayhem2012-086.i2p ehkjj4ptsagxlo27wpv4a5dk4zxqf4kg4p6fh35xrlz4y6mhe4eq
495 protokol.i2p f4xre35ehc5l6ianjvt3zcktxkjlyp2iwdje65qnu2j6vurhy6nq
496 proxynet.i2p 7gar5a3n4hzvsgi73iizo65mjza4kujf7feopfxuwu5p6wtwog5a
497 psi.i2p avviiexdngd32ccoy4kuckvc3mkf53ycvzbz6vz75vzhv4tbpk5a
498 psy.i2p s3elzoj3wo6v6wqu5ehd56vevpz2vrhhjc5m6mxoazicrl43y62q
499 psyco.i2p eoilbrgyaiikxzdtmk2zeoalteupjrvcu3ui23p4wvfqo25bb73q
500 pt.hiddenanswers.i2p o5jlxbbnx3byzgmihqye3kysop5jgl3unsrkmurbtr2nrnl2y74a
501 ptm.i2p 7dna5745ynxgogpjermnq26hwrqyjdlsibpjfmjxlwig247bjisa
502 ptt.i2p q7r32j7lc3xgrcw2ym33wv4lfgqbez7vtm4lts7n34qfe3iygeha
503 pull.git.repo.i2p 3so7htzxzz6h46qvjm3fbd735zl3lrblerlj2xxybhobublcv67q
504 push.git.repo.i2p jef4g5vxnqybm4zpouum3lzbl6ti6456q57nbyj5kfyldkempm3a
505 pycache.awup.i2p w45lkxdnqhil4sgzanmxce62sv3q4szeowcjb2e72a5y5vbhm4ra
506 r4sas.i2p 2gafixvoztrndawkmhfxamci5lgd3urwnilxqmlo6ittu552cndq
507 radio.r4sas.i2p cv72xsje5ihg6e24atitmhyk2cbml6eggi6b6fjfh2vgw62gdpla
508 ragnarok.i2p jpzw6kbuzz3ll2mfi3emcaan4gidyt7ysdhu62r5k5xawrva7kca
509 ransack.i2p mqamk4cfykdvhw5kjez2gnvse56gmnqxn7vkvvbuor4k4j2lbbnq
510 rasputin-sucks.i2p fdozdbyak4rul4jwpqfisbkcx4xbrkuvf2o5r6fd3xryyrjgvjiq
511 rebel.i2p nch2arl45crkyk6bklyk2hrdwjf5nztyxdtoshy6llhwqgxho5jq
512 red.i2p fzbdltgsg7jrpz7gmjfvhpcdnw5yrglwspnxqp4zoym3bglntzfa
513 redpanda.i2p 3wcnp6afz4cikqzdu2ktb5wfz7hb3ejdbpn7ocpy7fmeqyzbaiea
514 redzara.i2p ty7bt62rw5ryvk44dd3v5sua6c7wnbpxxqb6v4dohajmwmezi7va
515 reefer.i2p 4cde25mrrnt5n4nvp5tl62gej33nekfvq2viubmx4xdakhm5pfaa
516 relatelist.i2p utrer5zgnou72hs4eztmk37pmzdtfw3d6s23wwl7nk3lkqpzbdiq
517 repo.i2p uxe3lqueuuyklel23sf5h25zwgqgjwsofrqchhnptd5y6pedzbxa
518 repo.r4sas.i2p ymzx5zgt6qzdg6nhxnecdgbqjd34ery6mpqolnbyo5kcwxadnodq
519 reseed.i2p j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq
520 retrobbs-nntp.i2p fkyzl24oxcxvjzkx74t3533x7qjketzmvzk6bwn3d6hj5t7hlw6q
521 retrobbs.i2p mnn77stihntxdoade3ca2vcf456w6vhhvdsfepdvq5qggikvprxq
522 retrobbs2.i2p ejff7jtyaus37slkwgeqrrcmyhpj26carp7n27f5h6s5vlbeiy6q
523 revo-ua.i2p hpojpumki22xjwhmhe6zkiy44oanyn7u4ctcfe3in2ibwm5l32hq
524 riaa.i2p lfbezn7amkzhswnx7lb4lxihyggl2kuqo5c7vwkcv6bwqmr4cuoa
525 rideronthestorm.i2p xrdc2qc7quhumhglpbcuiqxr42nuffv4xj4a73jbr4ygepitibqq
526 romster.i2p eaf2stdqdbepylt53egvixdi34g2usvgi7a4oixsja6atkran43a
527 rootd.i2p mzbe5wofwn7eaqq4yefrmxizqaxoslwqxrv5qcv2opx5lnhg64dq
528 rospravosudie.i2p z55khrnlj6bzhs5zielutm6ae6t2bbhfuiujwlrp3teubqyc4w7q
529 rotten.i2p j4bm3rvezlejnb44elniagi5v2gazh7jaqrzhbod2pbxmgeb2frq
530 rpi.i2p 56p5qxsrvo5ereibevetw2qbj5bronmos7wxunku27g2s4kpbnlq
531 rslight.i2p bitag46q3465nylvzuikfwjcj7ewi4gjkjtvuxhn73f6vsxffyiq
532 rsync.thetower.i2p w4brpcdod7wnfqhwqrxyt4sbf2acouqfk5wyosfpq4mxq4s35kqa
533 ru.hiddenanswers.i2p o6rmndvggfwnuvxwyq54y667fmmurgveerlzufyrhub6w3vkagva
534 ru.i2p m7fqktjgtmsb3x7bvfrdx4tf7htnhytnz5qi2ujjcnph33u3hnja
535 rufurus.i2p 7msryymfdta3ssyz34qur6gi4jyfkvca5iyfmnceviipwu7g2wca
536 rus.i2p gh6655arkncnbrzq5tmq4xpn36734d4tdza6flbw5xppye2dt6ga
537 ruslibgen.i2p kk566cv37hivbjafiij5ryoui2ebxnm7b25gb3troniixopaj6nq
538 rutor.i2p tro5tvvtd2qg34naxhvqp4236it36jjaipbda5vnjmggp55navdq
539 salt.i2p 6aflphlze6btsbez5cm4x53ydrmwhqrkxsud535d3qjh4wq62rxq
540 sasquotch.i2p p6535uyfk2y6etc3t47vd3oqxydznqior5jxcvq5bdxe5kw5th6q
541 schwarzwald.i2p 4gokilzy73mmudufy3pohgatm42fcstx7uzg5hjvnfyphxpnphuq
542 sciencebooks.i2p ypftjpgck75swz3bnsu4nw7rmrlr2vqsn4mwivwt3zcc3rxln5cq
543 scp.duck.i2p ghbpsolpnveizxu4wbs7jbs2vj3kntnsexfcdleyhpqdhfpxleda
544 search.i2p nz4qj6xaw5fda3rsmsax6yjthqy4c7uak2j3dzcehtkgyso4q46q
545 secretchat.i2p cl3j2zxhpw6u6jevny45i557ojhwfxn4g375nnuqhy6lp27mry2q
546 secure.thetinhat.i2p 4q3qyzgz3ub5npbmt3vqqege5lg4zy62rhbgage4lpvnujwfpala
547 seeker.i2p ipll7sit24oyhnwawpvokz5u7dabq6klveuqpx3sbi6o5qemy2bq
548 seomon.i2p 5mvpsy4h45w4fx7upen7ay3vkrs5klphz5nptmtcqvc3fsajsm4q
549 septu.i2p 5lqvih7yzbqacfi63hwnmih57dxopu5g2o5o4e2aorq7bt4ooyra
550 serien.i2p 3z5k3anbbk32thinvwcy4g5al7dmb75fagcm3zgh4rzrt3maphda
551 ses.i2p 5qfoz6qfgbo7z5sdi26naxstpi2xiltamkcdbhmj6y6q2bo4inja
552 shiftfox.i2p wpvnuzslu7hjy4gujvnphtyckchdoxccrlhbyomsmjizykczyseq
553 shoieq3.i2p 3fjk4nfk3mccch4hdreghnyijcvovsi3yucjz3qzj5sxngqk5j6q
554 shoronil.i2p 7shqzgmb6tabiwrnwlasruq7pswy2d3emvfhaitehkqgod7i62sa
555 short.i2p z5mt5rvnanlex6r3x3jnjhzzfqpv36r4ylesynigytegjmebauba
556 sion.i2p lcbmmw2tvplvqh2dq5lmpxl3vnd5o4j3bdul5moa23deakjrso5q
557 sirup.i2p aohdp4yajnkitrtw7v2mo3sp7swuqhjfwlsi5xwd7dudzftumsma
558 site.games.i2p zeuczucfxeev3k7tvqlfcdpfbnqggheiknyyb5r2q4utn3d2auja
559 skank.i2p qiii4iqrj3fwv4ucaji2oykcvsob75jviycv3ghw7dhzxg2kq53q
560 slack.i2p gfcsh2yrb2tx7hyvmobriv52skz7qoobn7n7y7n6xaehhh4rpbja
561 slacker.i2p wq7m2wdguzweleb666ygv3bmfhha63zj74rub76vfesbyhsyk6iq
562 smeghead.i2p ojf4czveeuekxqkjvkszvv7eiop5dg7x2p6rgfzl4ng4xrjk6lja
563 smtp.mail.i2p kdn7zx7fgoe4bn5abaaj5cb3e4ql22fklb5veui5yajpj4cxapya
564 smtp.postman.i2p jj7pt6chsziz6oxxnzpqj7mzhxm2xfhcrbh7dl3tegifb577vx5q
565 socks1.tor.i2p sifawcdexgdmoc3krv46pvvz74nzd6fkju2vzykjxsx3egqsb6wq
566 sonax.i2p jmuxdhlok5ggojehesfjlit2e2q3fhzwwfxjndts7vzdshucbjjq
567 sponge.i2p o5hu7phy7udffuhts6w5wn5mw3sepwe3hyvw6kthti33wa2xn5tq
568 squid.i2p r4ll5zkbokgxlttqc2lrojvvey5yar4xr5prnndvnmggnqzjaeoq
569 squid2.i2p hum4wlwizbsckbudcklflei66qxhpxsdkyo4l2rn256smmjleila
570 sqz.i2p 3jvbwc7sy4lnhj25nj7yepx7omli4ulqirnawv3mz6qlhgokjgzq
571 ssh.i2p xpvdadaouc4qr75pteymyozc7mcsynjfkuqqkkla542lpcsqionq
572 stasher.i2p 6ilgpudnba4kroleunc2weh5txgoxys5yucij5gla6pjyki4oewa
573 stats.i2p 7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq
574 status.str4d.i2p ycyyjo3psqbo45nuz243xvgvwnmzlanzqbzxv3kh6gyjztv7425q
575 sto-man.i2p rg4eilfpe24ws6nctix63qw2dlvd2tqgwdcgdxzji6l5bc4dc7aa
576 str4d.i2p wrrwzdgsppwl2g2bdohhajz3dh45ui6u3y7yuop5ivvfzxtwnipa
577 stream.i2p prmbv3xm63ksoetnhbzqg4nzu2lhqdnqytgsydb7u3quxfrg7rna
578 streams.darkrealm.i2p ud3gcmvysjch4lbjr2khmhqpf7r2x5if4q43xkqdptl4k7lc4muq
579 striker.i2p 4gswsrfpbd44hwjoj33jbqfbwzxfkwpuplb3ydq5zm7nfu2pxvdq
580 subrosa.i2p g3lnglrnoual7wyabnwwv37uwhadgbxiqz36pf3f5cwfuxsx4mxq
581 subterra.i2p vdmhe4u26unzgd7ysq6w36ubjncms5wzbhzr2gq576sq4xut5zwq
582 sugadude.i2p yzjn76iyqard64wgggfrnywkxi7tbfkw7mjhpviqz3p2dguey4yq
583 suicidal.i2p yfamynllow5xiqbbca7eh5xn733wtnuti5bi4ovc7dwycntqmiuq
584 sungo.i2p h67s3jw56rwfyoxqxj3fngrluybsgxc2meendngkehzqowxnpj3q
585 surrender.adab.i2p jgz7xglgfgnjfklrytyn427np2ubipztlm5bxrtbiucayglukrta
586 susi.i2p qc6g2qfi2ccw7vjwpst6rwuofgzbeoewsb2usv7rubutf4gzqveq
587 syncline.i2p 5kcqmhislu3lmr7llgmdl72yu3efhyriljdc6wp774ftpwlcs5ra
588 syndie-project.i2p xa63tpfoaqt3zru2ehxjjfbpadwj4ha6qsdvtcqtyr3b7hmt4iaq
589 syndie.echelon.i2p vwrl2qmcif722fdkn3ldxcgz76df5cq4qypbndzthxwgmykyewta
590 syndie.i2p 7lm3yzpuejhpl4tt4l7o4ndqlu7hgijohofh7oaydx7q7kelenbq
591 syndiemedia.i2p 4lrbbblclodhobn3jadt5bf2yab2pxzoz4ey4a2cvrl44tdv3jma
592 tabak.i2p y5o2vwb6kart7ivpnbpk4yte3i7kf2dsx7fy3i6w7htqtxhmbzia
593 tahoeserve.i2p yhs7tsjeznxdenmdho5gjmk755wtredfzipb5t272oi5otipfkoa
594 tc.i2p qkv2yk6rof3rh7n3eelg5niujae6cmdzcpqbv3wsttedxtqqqj7a
595 telegram.i2p i6jow7hymogz2s42xq62gqgej2zdm4xtnmpc6vjcwktdxpdoupja
596 templar.i2p zxeralsujowfpyi2ynyjooxy222pzz4apc2qcwrfx5ikhf64et7q
597 terror.i2p wsijm6aqz4qtuyn2jedpx6imar5uq4yuhjdgtfqumxbqww47vbnq
598 thebland.i2p oiviukgwapzxsrwxsoucpqa47s3wt6nfuhfjxvgbqsyrze2mwrda
599 thebreton.i2p woutbsflcrlgppx4y7ag2kawlqijyenvlwrhbbvbkoaksuhf2hkq
600 thedarkside.i2p fxt3z33nzkrg5kjrk7bp5vvmu7w2vsn4i6jo6cily3hsm6u664ca
601 theland.i2p 26ppxbseda6xmim37ksarccdb4q5ctdagfmt2u5aba6xjh452zsa
602 thetower.i2p 3xqa5nype64y6fxgqjq6r5w2qpiqftoraj2niebumseat4cj654a
603 thornworld.i2p vinz4ygmodxarocntyjlfwk2wjpvzndlf4hxss2w2t3fk52oplva
604 tino.i2p e4bfnhvaofu4s67ztcgiskos2mqyhskid64dvlqexxs2c2bno3iq
605 tinyurl.i2p mc4oxv3v7dnyzpvok7v5qxkwtgjprgyz6w7x3tag4fipsen6rdwa
606 tome.i2p qktkxwawgixrm5lzofnj5n24zspbnzxy4pvjm7uvaxvmgwrsuvgq
607 tor-gw.meeh.i2p ounrqi7cfemnt66yhnhigt2u27fkctbvct527cp2522ozy3btjza
608 tor-www-proxy.i2p xov45rvjks5fe4ofmpblkj23bnwxgslbypbgvchbr7yul2ujej2q
609 torapa.i2p eejqjtpko6mdd4opvntbpsuandstrebxpbymfhix7avp5obrw5ta
610 torrentfinder.i2p mpc73okj7wq2xl6clofl64cn6v7vrvhpmi6d524nrsvbeuvjxalq
611 torrfreedom.i2p nfrjvknwcw47itotkzmk6mdlxmxfxsxhbhlr5ozhlsuavcogv4hq
612 trac.i2p kyioa2lgdi2za2fwfwajnb3ljz6zwlx7yzjdpnxnch5uw3iqn6ca
613 trac.i2p2.i2p i43xzkihpdq34f2jlmtgiyyay5quafg5rebog7tk7xil2c6kbyoa
614 tracker-fr.i2p qfrvqrfoqkistgzo2oxpfduz4ktkhtqopleozs3emblmm36fepea
615 tracker.awup.i2p dl47cno335ltvqm6noi5zcij5hpvbj7vjkzuofu262efvu6yp6cq
616 tracker.crypthost.i2p ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq
617 tracker.fr.i2p rzwqr7pfibq5wlcq4a7akm6ohfyhz7hchmy4wz5t55lhd7dwao5q
618 tracker.i2p lsjcplya2b4hhmezz2jy5gqh6zlk3nskisjkhhwapy3jjly4ds5q
619 tracker.lodikon.i2p q2a7tqlyddbyhxhtuia4bmtqpohpp266wsnrkm6cgoahdqrjo3ra
620 tracker.mastertracker.i2p tiwurhqvaaguwpz2shdahqmcfze5ejre52ed2rmoadnjkkilskda
621 tracker.postman.i2p jfcylf4j3gfmqogkltwy7v5m47wp4h7ffrnfsva6grfdavdn7ueq
622 tracker.psi.i2p vmow3h54yljn7zvzbqepdddt5fmygijujycod2q6yznpy2rrzuwa
623 tracker.thebland.i2p s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq
624 tracker.welterde.i2p cfmqlafjfmgkzbt4r3jsfyhgsr5abgxryl6fnz3d3y5a365di5aa
625 tracker2.postman.i2p ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna
626 traditio.i2p wkpjjloylf6jopu2itgpktr45t2xvpjijxilxd5tq4i7wkqgwhhq
627 trevorreznik.i2p wc2z6o5fxm2saqzpfcawr63lejwccvzkysmgtfudkrigqopzfdma
628 true.i2p pdilhl5vmefyzrrnmak5bnmxqxk2pmw7rpy4f7wbaeppqu2vvugq
629 trwcln.i2p evml6jiiujhulsgxkdu3wcmkwbokxlv4is6w5qj46tp3ajz3hqzq
630 trypanom.i2p tgv5acj4khwvr6t44cmryohybd2e5o2kndysnzae6qwcr4hzda3q
631 ts.i2p nebcjgfx3f7q4wzihqmguwcdeopaf7f6wyk2dojw4bcuku472zxq
632 ttc.i2p wb4tsfyvfv4idgrultsq6o7inza4fxkc7dijsfpncbx7zko4cdlq
633 ttp.i2p uuczclxejmetohwf2vqewovx3qcumdfh5zecjb3xkcdmk6e5j72a
634 tumbach.i2p u6pciacxnpbsq7nwc3tgutywochfd6aysgayijr7jxzoysgxklvq
635 tutorials.i2p zy37tq6ynucp3ufoyeegswqjaeofmj57cpm5ecd7nbanh2h6f2ja
636 ugha.i2p z3f3owc72awbywk4p6qb5l2mxgitvs6ejztggbpn2a3ddmymfjda
637 uk.i2p vydbychnep3mzkzhg43ptewp242issy47whamfbxodc4ma6wc63a
638 underground.i2p dlnuthb6tpw3kchlb7xoztyspy4ehlggjhl44l64vbcrulrfeica
639 underscore.i2p 3gmezyig6gvsjbpkq2kihoskpuqpkfrajmhhm7hpyrjuvtasgepa
640 unqueued.i2p 3gvn4kwd7z74jxc2sn4ucx52dpvpscxbzjluux3ul4t3eu5g64xq
641 up.i2p 25it5olgdo7pht25z6buzd32sw7jvc65oziqeuocfozfhgua655q
642 update.dg.i2p iqj6ysfh3wl26m4buvyna73yhduifv523l7bwuexxak4mgldexja
643 update.killyourtv.i2p gqdfg25jlqtm35qnmt4b7r53d6u2vep4ob23fwd42iyy4j6cvdqq
644 update.postman.i2p u5rbu6yohfafplp6lgbbmmcuip34s7g3zqdd63cp27dl3nbd7gtq
645 utansans.i2p u2oyre7ygqv4qs5xjjijfg3x7ddwtod6nqwgbomuuzljzvnq4rda
646 v2mail.i2p 4gg7fykcqe7oaqt4w5fmlarnia7vtmwkv3h45zzgoj6o6crryg5a
647 vadino.i2p aalttzlt3z25ktokesceweabm5yyhhvml2z3rfotndgpfyh6myra
648 visibility.i2p pwgma3snbsgkddxgb54mrxxkt3l4jzchrtp52vxmw7rbkjygylxq
649 volatile.i2p q6rve733tvhgyys57jfw4fymqf3xsnza6dqailcdjcq7w4fa5m3a
650 vpnbest.i2p ov5f74ndsy5rfkuyps56waf42vxncufqu5rzm3vsnxkdtogccaea
651 vudu.i2p 3zlwci7pvgep2igygzyjej24ue7mjsktlhaff6crpsr75yquak2q
652 w.i2p j2xorlcb3qxubnthzqu7lt4fvxqn63it4ikwmze55yjkzeeampuq
653 wa11ed.city.i2p 7mxwtmala3ycg2sybjwwfil7s6dqck2fbemeutghhwu73rznmqoa
654 wahoo.i2p vqe5vkpe5wbda7lwekcd2jaj44ar3rawgv54u5rcolezbg5f5vwa
655 wallet.gostcoin.i2p reuvum7lgetglafn72chypesvto773oy53zumagrpigkckybrwda
656 wallsgetbombed.i2p tzhea5d65fllm4263wztghgw4ijdgibsca5xsecp6lk4xlsbdeuq
657 web.telegram.i2p re6cgwg2yrkgaixlqvt5ufajbb3w42fsldlq7k5brpvnd5gp6x5a
658 wiht.i2p yojmpj3sh76g3i6ogzgsf7eouipdgdij5o2blcpdgmu5oyjk5xca
659 wiki.fr.i2p lrqa7hw52uxjb5q3pedmjs6hzos5zrod4y6a4e25hu7vcjhohvxq
660 wiki.ilita.i2p r233yskmowqe4od4he4b37wydr5fqzvj3z77v5fdei2etp2kg34a
661 wintermute.i2p 4gvlfrdy2rkmem33c342tjntpvqik65wekcvm4275qbkuwotoila
662 wspucktracker.i2p ubd2txda3kllumx7ftg4unzgqy536cn6dd2ax6mlhodczfas7rgq
663 www.aum.i2p 3xolizygkzkqrldncjqsb734szznw2u36lliceuacqnbs2n65aeq
664 www.baffled.i2p lqrsfslwu4xnubkk2hofhmuvvr4dia2zevxefinbzdsjurvehtqq
665 www.fr.i2p rmkgvlfwo3vkb3xrr6epoypxasdzzuilv3sckcqbo6c4os5jo2ea
666 www.i2p ojxyenivrrqvycgbxbm3phgisu5abspzq4g2us4fjlwz4tx222va
667 www.i2p2.i2p rjxwbsw4zjhv4zsplma6jmf5nr24e4ymvvbycd3swgiinbvg7oga
668 www.imule.i2p 657xcllunctawyjtar5kgh3wpt6z4l7ba6mmam5rf7hev5w2lsvq
669 www.infoserver.i2p fq7xhxkdcauhwn4loufcadiiy24zbei25elnup33a3gfrdzrtlyq
670 www.janonymous.i2p vosqx5qw22hwrzcgsm4ib7hymf5ryovsbtaexqrzmnzshy5bhakq
671 www.mail.i2p nctas6ioo7aaekfstv3o45yh6ywzwa3vznrdae52ouupzke5pyba
672 www.nntp.i2p kly3o7zmetuwyz7xonnhttw4lj2244pkbibjz26uflyfte3b3dka
673 www.postman.i2p rb3srw2gaooyw63q62cp4udrxxa6molr2irbkgrloveylpkkblhq
674 www.syndie.i2p vojgy5ep4wffmtpjmpnbpa4gq64bgn4yicuw6qmhbm6nqa2ysrva
675 www1.squid.i2p vbh3bltd2duwbukafgj6f6vfi6aigwso7snucp5zohnf66a2hkpa
676 xc.i2p mt45a2z3sb2iyy2mwauj4rwa2lwu4peanfy6gx6ybidwnbasusyq
677 xeha.i2p oartgetziabrdemxctowp7bbeggc7ktmj7tr4qgk5y5jcz4prbtq
678 xilog.i2p eoc5i5q52hutnmsmq56edvooulutaxfikddgdz27otmgtsxmiloq
679 xmpp.crypthost.i2p ittkqpjuliwsdewdugkhvgzstejr2jp5tzou7p332lxx4xw7srba
680 xmpp.rpi.i2p 3yv65pfwiwfuv4ciwtx34clqps6o2mc3vtyltcbqdkcki6untbca
681 xn--l2bl5aw.i2p d2epikjh5crt2l5xjmtceqw2ho44hzp6x3u7hgjrd4mi4wywikwa
682 xolotl.i2p rwr6rrlmrotxfkxt22mah42cycliy2g5k7hgxyxkpcyyxkd2bgwq
683 xotc.i2p gqgvzum3xdgtaahkjfw3layb33vjrucmw5btyhrppm463cz3c5oq
684 z-lab.i2p s6g2pz3mrwzsl4ts65ox3scqawfj7mzvd7hn2ekiiycawopkriba
685 zab.i2p n4xen5sohufgjhv327ex4qra77f4tpqohlcyoa3atoboknzqazeq
686 zcash.i2p zcashmliuw3yd2ptfyd5sadatcpyxj4ldiqahtjzg73cgoevxp4q
687 zener.i2p mcbyglflte3dhwhqyafsfpnqtcapqkv2sepqd62wzd7fo2dzz4ca
688 zerobin.i2p 3564erslxzaoucqasxsjerk4jz2xril7j2cbzd4p7flpb4ut67hq
689 zeroman.i2p gq77fmto535koofcd53f6yzcc5y57ccrxg3pb6twhcodc7v5dutq
690 zeronet.i2p fe6pk5sibhkr64veqxkfochdfptehyxrrbs3edwjs5ckjbjn4bna
691 znc.i2p uw2yt6njjl676fupd72hiezwmd4ouuywowrph6fvhkzhlnvp7jwa
692 znc.str4d.i2p ufkajv3stxpxlwgwwb2ae6oixdjircnbwog77qxpxv7nt67rpcxq
693 zzz.i2p ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq

1
android/assets/certificates

@ -1 +0,0 @@ @@ -1 +0,0 @@
../../contrib/certificates

92
android/assets/i2pd.conf

@ -1,92 +0,0 @@ @@ -1,92 +0,0 @@
## Configuration file for a typical i2pd user
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
## for more options you can use in this file.
#logfile = /sdcard/i2pd/i2pd.log
loglevel = none
#tunnelsdir = /sdcard/i2pd/tunnels.d
# host = 1.2.3.4
# port = 4567
ipv4 = true
ipv6 = false
# ntcp = true
# ntcpproxy = http://127.0.0.1:8118
# ssu = true
bandwidth = L
# share = 100
# notransit = true
# floodfill = true
[ntcp2]
enabled = true
[http]
enabled = true
address = 127.0.0.1
port = 7070
# auth = true
# user = i2pd
# pass = changeme
[httpproxy]
enabled = true
address = 127.0.0.1
port = 4444
inbound.length = 1
inbound.quantity = 5
outbound.length = 1
outbound.quantity = 5
signaturetype=7
i2cp.leaseSetType=3
i2cp.leaseSetEncType=0,4
keys = proxy-keys.dat
# addresshelper = true
# outproxy = http://false.i2p
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc.
[socksproxy]
enabled = true
address = 127.0.0.1
port = 4447
keys = proxy-keys.dat
# outproxy.enabled = false
# outproxy = 127.0.0.1
# outproxyport = 9050
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc.
[sam]
enabled = false
# address = 127.0.0.1
# port = 7656
[precomputation]
elgamal = true
[upnp]
enabled = true
# name = I2Pd
[reseed]
verify = true
## Path to local reseed data file (.su3) for manual reseeding
# file = /path/to/i2pseeds.su3
## or HTTPS URL to reseed from
# file = https://legit-website.com/i2pseeds.su3
## Path to local ZIP file or HTTPS URL to reseed from
# zipfile = /path/to/netDb.zip
## If you run i2pd behind a proxy server, set proxy server for reseeding here
## Should be http://address:port or socks://address:port
# proxy = http://127.0.0.1:8118
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default
# threshold = 25
[limits]
transittunnels = 50
[persist]
profiles = false

3
android/assets/subscriptions.txt

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
http://inr.i2p/export/alive-hosts.txt
http://stats.i2p/cgi-bin/newhosts.txt
http://i2p-projekt.i2p/hosts.txt

33
android/assets/tunnels.conf

@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
#[IRC-IRC2P]
#type = client
#address = 127.0.0.1
#port = 6668
#destination = irc.postman.i2p
#destinationport = 6667
#keys = irc-keys.dat
#[IRC-ILITA]
#type = client
#address = 127.0.0.1
#port = 6669
#destination = irc.ilita.i2p
#destinationport = 6667
#keys = irc-keys.dat
#[SMTP]
#type = client
#address = 127.0.0.1
#port = 7659
#destination = smtp.postman.i2p
#destinationport = 25
#keys = smtp-keys.dat
#[POP3]
#type = client
#address = 127.0.0.1
#port = 7660
#destination = pop.postman.i2p
#destinationport = 110
#keys = pop3-keys.dat
# see more examples at https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/

1
android/assets/tunnels.d

@ -1 +0,0 @@ @@ -1 +0,0 @@
../../contrib/tunnels.d

105
android/build.gradle

@ -1,105 +0,0 @@ @@ -1,105 +0,0 @@
buildscript {
repositories {
mavenCentral()
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
}
}
apply plugin: 'com.android.application'
repositories {
jcenter()
maven {
url 'https://maven.google.com'
}
google()
}
dependencies {
implementation 'androidx.core:core:1.0.2'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
}
android {
compileSdkVersion 29
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "org.purplei2p.i2pd"
targetSdkVersion 29
minSdkVersion 14
versionCode 2350
versionName "2.35.0"
setProperty("archivesBaseName", archivesBaseName + "-" + versionName)
ndk {
abiFilters 'armeabi-v7a'
abiFilters 'x86'
//abiFilters 'arm64-v8a'
//abiFilters 'x86_64'
}
externalNativeBuild {
ndkBuild {
arguments "-j3"
}
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
jniLibs.srcDirs = ['libs']
assets.srcDirs = ['assets']
}
}
splits {
abi {
// change that to true if you need splitted apk
enable true
reset()
//include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
include "armeabi-v7a", "x86"
universalApk true
}
}
signingConfigs {
orignal {
storeFile file("i2pdapk.jks")
storePassword "android"
keyAlias "i2pdapk"
keyPassword "android"
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.orignal
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
externalNativeBuild {
ndkBuild {
path './jni/Android.mk'
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
}
ext.abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'arm64-v8a': 3, 'x86_64': 4]
import com.android.build.OutputFile
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
if (baseAbiVersionCode != null) {
output.versionCodeOverride = baseAbiVersionCode + variant.versionCode
}
}
}

96
android/build.xml

@ -1,96 +0,0 @@ @@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="i2pd" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Insert sdk.dir=... into './local.properties'. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<fail
message="ndk.dir is missing. Insert ndk.dir=... into './local.properties'."
unless="ndk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

3
android/gradle.properties

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
android.enableJetifier=true
android.useAndroidX=true
org.gradle.parallel=true

BIN
android/gradle/wrapper/gradle-wrapper.jar vendored

Binary file not shown.

6
android/gradle/wrapper/gradle-wrapper.properties vendored

@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
#Tue Aug 20 14:39:08 MSK 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

172
android/gradlew vendored

@ -1,172 +0,0 @@ @@ -1,172 +0,0 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
android/gradlew.bat vendored

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

73
android/jni/Android.mk

@ -1,73 +0,0 @@ @@ -1,73 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := i2pd
LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH)
LOCAL_STATIC_LIBRARIES := \
boost_system \
boost_date_time \
boost_filesystem \
boost_program_options \
crypto ssl \
miniupnpc
LOCAL_LDLIBS := -lz
LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
$(DAEMON_SRC_PATH)/Daemon.cpp \
$(DAEMON_SRC_PATH)/UPnP.cpp \
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
$(DAEMON_SRC_PATH)/I2PControl.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_system
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_date_time
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_filesystem
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := boost_program_options
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libssl.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include
LOCAL_STATIC_LIBRARIES := crypto
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := miniupnpc
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include
include $(PREBUILT_STATIC_LIBRARY)

36
android/jni/Application.mk

@ -1,36 +0,0 @@ @@ -1,36 +0,0 @@
#APP_ABI := armeabi-v7a x86
#APP_PLATFORM := android-14
# ABI arm64-v8a and x86_64 supported only from platform-21
#APP_ABI := arm64-v8a x86_64
#APP_PLATFORM := android-21
NDK_TOOLCHAIN_VERSION := clang
#APP_STL := c++_shared
APP_STL := c++_static
# Enable c++17 extensions in source code
APP_CPPFLAGS += -std=c++17 -fexceptions -frtti
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_CPPFLAGS += -DANDROID_ARM7A
endif
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
# change to your own
I2PD_LIBS_PATH = /path/to/libraries
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs
# don't change me
I2PD_SRC_PATH = $(PWD)/..
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon

222
android/jni/DaemonAndroid.cpp

@ -1,222 +0,0 @@ @@ -1,222 +0,0 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <iostream>
#include <chrono>
#include <thread>
#include <exception>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception_ptr.hpp>
//#include "mainwindow.h"
#include "FS.h"
#include "DaemonAndroid.h"
#include "Daemon.h"
namespace i2p
{
namespace android
{
/* Worker::Worker (DaemonAndroidImpl& daemon):
m_Daemon (daemon)
{
}
void Worker::startDaemon()
{
Log.d(TAG"Performing daemon start...");
m_Daemon.start();
Log.d(TAG"Daemon started.");
emit resultReady();
}
void Worker::restartDaemon()
{
Log.d(TAG"Performing daemon restart...");
m_Daemon.restart();
Log.d(TAG"Daemon restarted.");
emit resultReady();
}
void Worker::stopDaemon() {
Log.d(TAG"Performing daemon stop...");
m_Daemon.stop();
Log.d(TAG"Daemon stopped.");
emit resultReady();
}
Controller::Controller(DaemonAndroidImpl& daemon):
m_Daemon (daemon)
{
Worker *worker = new Worker (m_Daemon);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
Controller::~Controller()
{
Log.d(TAG"Closing and waiting for daemon worker thread...");
workerThread.quit();
workerThread.wait();
Log.d(TAG"Waiting for daemon worker thread finished.");
if(m_Daemon.isRunning())
{
Log.d(TAG"Stopping the daemon...");
m_Daemon.stop();
Log.d(TAG"Stopped the daemon.");
}
}
*/
std::string dataDir = "";
DaemonAndroidImpl::DaemonAndroidImpl ()
//:
/*mutex(nullptr), */
//m_IsRunning(false),
//m_RunningChangedCallback(nullptr)
{
}
DaemonAndroidImpl::~DaemonAndroidImpl ()
{
//delete mutex;
}
bool DaemonAndroidImpl::init(int argc, char* argv[])
{
//mutex=new QMutex(QMutex::Recursive);
//setRunningCallback(0);
//m_IsRunning=false;
// make sure assets are ready before proceed
i2p::fs::DetectDataDir(dataDir, false);
int numAttempts = 0;
do
{
if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready
numAttempts++;
std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second
}
while (numAttempts <= 10); // 10 seconds max
return Daemon.init(argc,argv);
}
void DaemonAndroidImpl::start()
{
//QMutexLocker locker(mutex);
//setRunning(true);
Daemon.start();
}
void DaemonAndroidImpl::stop()
{
//QMutexLocker locker(mutex);
Daemon.stop();
//setRunning(false);
}
void DaemonAndroidImpl::restart()
{
//QMutexLocker locker(mutex);
stop();
start();
}
/*
void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb)
{
m_RunningChangedCallback = cb;
}
bool DaemonAndroidImpl::isRunning()
{
return m_IsRunning;
}
void DaemonAndroidImpl::setRunning(bool newValue)
{
bool oldValue = m_IsRunning;
if(oldValue!=newValue)
{
m_IsRunning = newValue;
if(m_RunningChangedCallback)
m_RunningChangedCallback();
}
}
*/
static DaemonAndroidImpl daemon;
static char* argv[1]={strdup("tmp")};
/**
* returns error details if failed
* returns "ok" if daemon initialized and started okay
*/
std::string start(/*int argc, char* argv[]*/)
{
try
{
//int result;
{
//Log.d(TAG"Initialising the daemon...");
bool daemonInitSuccess = daemon.init(1,argv);
if(!daemonInitSuccess)
{
//QMessageBox::critical(0, "Error", "Daemon init failed");
return "Daemon init failed";
}
//Log.d(TAG"Initialised, creating the main window...");
//MainWindow w;
//Log.d(TAG"Before main window.show()...");
//w.show ();
{
//i2p::qt::Controller daemonQtController(daemon);
//Log.d(TAG"Starting the daemon...");
//emit daemonQtController.startDaemon();
//daemon.start ();
//Log.d(TAG"Starting GUI event loop...");
//result = app.exec();
//daemon.stop ();
daemon.start();
}
}
//QMessageBox::information(&w, "Debug", "demon stopped");
//Log.d(TAG"Exiting the application");
//return result;
}
catch (boost::exception& ex)
{
std::stringstream ss;
ss << boost::diagnostic_information(ex);
return ss.str();
}
catch (std::exception& ex)
{
std::stringstream ss;
ss << ex.what();
return ss.str();
}
catch(...)
{
return "unknown exception";
}
return "ok";
}
void stop()
{
daemon.stop();
}
void SetDataDir(std::string jdataDir)
{
dataDir = jdataDir;
}
}
}

97
android/jni/DaemonAndroid.h

@ -1,97 +0,0 @@ @@ -1,97 +0,0 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef DAEMON_ANDROID_H
#define DAEMON_ANDROID_H
#include <string>
namespace i2p
{
namespace android
{
class DaemonAndroidImpl
{
public:
DaemonAndroidImpl ();
~DaemonAndroidImpl ();
//typedef void (*runningChangedCallback)();
/**
* @return success
*/
bool init(int argc, char* argv[]);
void start();
void stop();
void restart();
//void setRunningCallback(runningChangedCallback cb);
//bool isRunning();
private:
//void setRunning(bool running);
private:
//QMutex* mutex;
//bool m_IsRunning;
//runningChangedCallback m_RunningChangedCallback;
};
/**
* returns "ok" if daemon init failed
* returns errinfo if daemon initialized and started okay
*/
std::string start();
// stops the daemon
void stop();
// set datadir received from jni
void SetDataDir(std::string jdataDir);
/*
class Worker : public QObject
{
Q_OBJECT
public:
Worker (DaemonAndroidImpl& daemon);
private:
DaemonAndroidImpl& m_Daemon;
public slots:
void startDaemon();
void restartDaemon();
void stopDaemon();
signals:
void resultReady();
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller(DaemonAndroidImpl& daemon);
~Controller();
private:
DaemonAndroidImpl& m_Daemon;
public slots:
void handleResults(){}
signals:
void startDaemon();
void stopDaemon();
void restartDaemon();
};
*/
}
}
#endif // DAEMON_ANDROID_H

114
android/jni/i2pd_android.cpp

@ -1,114 +0,0 @@ @@ -1,114 +0,0 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#include <jni.h>
#include "org_purplei2p_i2pd_I2PD_JNI.h"
#include "DaemonAndroid.h"
#include "RouterContext.h"
#include "ClientContext.h"
#include "Transports.h"
#include "Tunnel.h"
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
(JNIEnv *env, jclass clazz) {
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a/NEON (hard-float)"
#else
#define ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a (hard-float)"
#else
#define ABI "armeabi-v7a"
#endif
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__x86_64__)
#define ABI "x86_64"
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
#define ABI "mips64"
#elif defined(__mips__)
#define ABI "mips"
#elif defined(__aarch64__)
#define ABI "arm64-v8a"
#else
#define ABI "unknown"
#endif
return env->NewStringUTF(ABI);
}
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
(JNIEnv *env, jclass clazz) {
return env->NewStringUTF(i2p::android::start().c_str());
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
(JNIEnv *env, jclass clazz) {
i2p::android::stop();
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
(JNIEnv *env, jclass clazz) {
i2p::context.SetAcceptsTunnels (false);
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
(JNIEnv *env, jclass clazz) {
i2p::context.SetAcceptsTunnels (true);
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs
(JNIEnv *env, jclass clazz) {
i2p::client::context.ReloadConfig();
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
(JNIEnv *env, jclass clazz, jboolean isConnected) {
bool isConnectedBool = (bool) isConnected;
i2p::transport::transports.SetOnline (isConnectedBool);
}
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir
(JNIEnv *env, jclass clazz, jstring jdataDir) {
/*
// Method 1: convert UTF-16 jstring to std::string (https://stackoverflow.com/a/41820336)
const jclass stringClass = env->GetObjectClass(jdataDir);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jdataDir, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t) env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string dataDir = std::string((char *)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass); */
// Method 2: get string chars and make char array.
auto dataDir = env->GetStringUTFChars(jdataDir, NULL);
env->ReleaseStringUTFChars(jdataDir, dataDir);
// Set DataDir
i2p::android::SetDataDir(dataDir);
}
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount
(JNIEnv *env, jclass clazz) {
return i2p::tunnel::tunnels.CountTransitTunnels();
}

53
android/jni/org_purplei2p_i2pd_I2PD_JNI.h

@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_purplei2p_i2pd_I2PD_JNI */
#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI
#define _Included_org_purplei2p_i2pd_I2PD_JNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_purplei2p_i2pd_I2PD_JNI
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
(JNIEnv *, jclass);
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs
(JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
(JNIEnv * env, jclass clazz, jboolean isConnected);
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir
(JNIEnv *env, jclass clazz, jstring jdataDir);
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif

20
android/proguard-project.txt

@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

14
android/project.properties

@ -1,14 +0,0 @@ @@ -1,14 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-29

BIN
android/res/drawable/icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

BIN
android/res/drawable/itoopie_notification_icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

26
android/res/layout/activity_perms_asker.xml

@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
<LinearLayout android:id="@+id/main_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/vertical_page_margin"
android:paddingLeft="@dimen/horizontal_page_margin"
android:paddingRight="@dimen/horizontal_page_margin"
android:paddingTop="@dimen/vertical_page_margin"
tools:context=".I2PDPermsAskerActivity">
<TextView
android:id="@+id/textview_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/horizontal_page_margin"
android:visibility="gone" />
<Button
android:id="@+id/button_request_write_ext_storage_perms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/retryPermRequest"
android:visibility="gone" />
</LinearLayout>

25
android/res/layout/activity_perms_explanation.xml

@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
<LinearLayout android:id="@+id/layout_prompt"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/vertical_page_margin"
android:paddingLeft="@dimen/horizontal_page_margin"
android:paddingRight="@dimen/horizontal_page_margin"
android:paddingTop="@dimen/vertical_page_margin"
tools:context=".I2PDPermsAskerActivity">
<TextView
android:id="@+id/textview_explanation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/horizontal_page_margin"
android:text="@string/permRequired" />
<Button
android:id="@+id/button_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ok" />
</LinearLayout>

22
android/res/layout/activity_web_console.xml

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/layout_prompt"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".WebConsoleActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/swipe">
<WebView
android:id="@+id/webview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

31
android/res/menu/options_main.xml

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".I2PDActivity">
<group android:id="@+id/group_various">
<item
android:id="@+id/action_battery_otimizations"
android:title="@string/menu_item_battery_optimizations_str" />
</group>
<group android:id="@+id/group_i2pd_control">
<item
android:id="@+id/action_start_webview"
android:orderInCategory="96"
android:title="@string/action_start_webview" />
<item
android:id="@+id/action_reload_tunnels_config"
android:orderInCategory="97"
android:title="@string/action_reload_tunnels_config" />
<item
android:id="@+id/action_graceful_stop"
android:orderInCategory="98"
android:title="@string/action_graceful_stop" />
<item
android:id="@+id/action_stop"
android:orderInCategory="99"
android:title="@string/action_stop" />
</group>
</menu>

40
android/res/values-ru/strings.xml

@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">i2pd</string>
<string name="action_stop">Остановить</string>
<string name="action_graceful_stop">Корректная остановка</string>
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string>
<string name="action_reload_tunnels_config">Перезагрузить туннели</string>
<string name="action_start_webview">Открыть Веб Консоль</string>
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string>
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string>
<string name="gracefulShutdownInProgress">Корректная остановка запущена</string>
<string name="already_stopped">Уже остановлено</string>
<string name="uninitialized">Приложение инициализируется</string>
<string name="starting">Приложение запускается</string>
<string name="jniLibraryLoaded">Загружены JNI библиотеки</string>
<string name="startedOkay">Приложение запущено</string>
<string name="startFailed">Запуск не удался</string>
<string name="stopped">Приложение было остановлено</string>
<string name="remaining">осталось</string>
<string name="title_activity_i2_pdperms_asker_prompt">Запрос</string>
<string name="permDenied">Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения</string>
<string name="permRequired">Права на запись на SD карту необходимы для записи ключей и других файлов в папку I2PD на внутренней памяти.</string>
<string name="retryPermRequest">Повторить запрос прав на запись на SD карту</string>
<string name="menu_item_battery_optimizations_str">Оптимизации аккумулятора</string>
<string name="battery_optimizations_enabled">Оптимизации аккумулятора включены</string>
<string name="battery_optimizations_enabled_explained">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\nРекомендуется отключить эти оптимизации.</string>
<string name="battery_optimizations_enabled_dialog">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций.</string>
<string name="continue_str">Продолжить</string>
<string name="device_does_not_support_disabling_battery_optimizations">Ваша версия Андроид не поддерживает отключение оптимизаций аккумулятора</string>
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений.</string>
<string name="shutdown_canceled">Плановая остановка отменена</string>
<string name="tunnels_reloading">Перезагрузка конфигурации туннелей...</string>
</resources>

41
android/res/values/strings.xml

@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_name">i2pd</string>
<string name="action_stop">Stop</string>
<string name="action_graceful_stop">Graceful Stop</string>
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string>
<string name="action_reload_tunnels_config">Reload tunnels</string>
<string name="action_start_webview">Open Web Console</string>
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
<string name="gracefulShutdownInProgress">Graceful shutdown in progress</string>
<string name="already_stopped">Already stopped</string>
<string name="uninitialized">Application initializing</string>
<string name="starting">Application starting</string>
<string name="jniLibraryLoaded">Loaded JNI libraries</string>
<string name="startedOkay">Application Started</string>
<string name="startFailed">Start failed</string>
<string name="stopped">Application stopped</string>
<string name="remaining">remaining</string>
<string name="ok">OK</string>
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string>
<string name="permDenied">SD card write permission denied, you need to allow this to continue</string>
<string name="permRequired">SD card write access is required to write the keys and other files to the I2PD folder on SD card.</string>
<string name="retryPermRequest">Retry requesting the SD card write permissions</string>
<string name="menu_item_battery_optimizations_str">Battery Optimizations</string>
<string name="battery_optimizations_enabled">Battery optimizations enabled</string>
<string name="battery_optimizations_enabled_explained">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to allow disabling those battery optimizations.</string>
<string name="battery_optimizations_enabled_dialog">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to allow to disable those.</string>
<string name="continue_str">Continue</string>
<string name="device_does_not_support_disabling_battery_optimizations">Your Android version does not support opting out of battery optimizations</string>
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Your Android OS version does not support showing the dialog for battery optimizations for applications.</string>
<string name="shutdown_canceled">Planned shutdown canceled</string>
<string name="tunnels_reloading">Reloading tunnels config...</string>
</resources>

16
android/res/values/template-dimens.xml

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
<resources>
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
<dimen name="margin_tiny">4dp</dimen>
<dimen name="margin_small">8dp</dimen>
<dimen name="margin_medium">16dp</dimen>
<dimen name="margin_large">32dp</dimen>
<dimen name="margin_huge">64dp</dimen>
<!-- Semantic definitions -->
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
</resources>

1
android/settings.gradle

@ -1 +0,0 @@ @@ -1 +0,0 @@
rootProject.name = "i2pd"

374
android/src/org/purplei2p/i2pd/DaemonWrapper.java

@ -1,374 +0,0 @@ @@ -1,374 +0,0 @@
package org.purplei2p.i2pd;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
import android.annotation.TargetApi;
import android.content.res.AssetManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import androidx.annotation.RequiresApi;
public class DaemonWrapper {
private static final String TAG = "i2pd";
private final AssetManager assetManager;
private final ConnectivityManager connectivityManager;
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/";
private boolean assetsCopied;
public interface StateUpdateListener {
void daemonStateUpdate(State oldValue, State newValue);
}
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
public synchronized void addStateChangeListener(StateUpdateListener listener) {
stateUpdateListeners.add(listener);
}
public synchronized void removeStateChangeListener(StateUpdateListener listener) {
stateUpdateListeners.remove(listener);
}
private synchronized void setState(State newState) {
if (newState == null)
throw new NullPointerException();
State oldState = state;
if (oldState == null)
throw new NullPointerException();
if (oldState.equals(newState))
return;
state = newState;
fireStateUpdate1(oldState, newState);
}
public synchronized void stopAcceptingTunnels() {
if (isStartedOkay()) {
setState(State.gracefulShutdownInProgress);
I2PD_JNI.stopAcceptingTunnels();
}
}
public synchronized void startAcceptingTunnels() {
if (isStartedOkay()) {
setState(State.startedOkay);
I2PD_JNI.startAcceptingTunnels();
}
}
public synchronized void reloadTunnelsConfigs() {
if (isStartedOkay()) {
I2PD_JNI.reloadTunnelsConfigs();
}
}
public int getTransitTunnelsCount() {
return I2PD_JNI.GetTransitTunnelsCount();
}
public enum State {
uninitialized(R.string.uninitialized),
starting(R.string.starting),
jniLibraryLoaded(R.string.jniLibraryLoaded),
startedOkay(R.string.startedOkay),
startFailed(R.string.startFailed),
gracefulShutdownInProgress(R.string.gracefulShutdownInProgress),
stopped(R.string.stopped);
State(int statusStringResourceId) {
this.statusStringResourceId = statusStringResourceId;
}
private final int statusStringResourceId;
public int getStatusStringResourceId() {
return statusStringResourceId;
}
public boolean isStartedOkay() {
return equals(State.startedOkay) || equals(State.gracefulShutdownInProgress);
}
}
private volatile State state = State.uninitialized;
public State getState() {
return state;
}
public DaemonWrapper(AssetManager assetManager, ConnectivityManager connectivityManager){
this.assetManager = assetManager;
this.connectivityManager = connectivityManager;
setState(State.starting);
new Thread(() -> {
try {
processAssets();
I2PD_JNI.loadLibraries();
setState(State.jniLibraryLoaded);
registerNetworkCallback();
} catch (Throwable tr) {
lastThrowable = tr;
setState(State.startFailed);
return;
}
try {
synchronized (DaemonWrapper.this) {
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
daemonStartResult = I2PD_JNI.startDaemon();
if ("ok".equals(daemonStartResult)) {
setState(State.startedOkay);
} else
setState(State.startFailed);
}
} catch (Throwable tr) {
lastThrowable = tr;
setState(State.startFailed);
}
}, "i2pdDaemonStart").start();
}
private Throwable lastThrowable;
private String daemonStartResult = "N/A";
private void fireStateUpdate1(State oldValue, State newValue) {
Log.i(TAG, "daemon state change: " + state);
for (StateUpdateListener listener : stateUpdateListeners) {
try {
listener.daemonStateUpdate(oldValue, newValue);
} catch (Throwable tr) {
Log.e(TAG, "exception in listener ignored", tr);
}
}
}
public Throwable getLastThrowable() {
return lastThrowable;
}
public String getDaemonStartResult() {
return daemonStartResult;
}
public boolean isStartedOkay() {
return getState().isStartedOkay();
}
public synchronized void stopDaemon() {
if (isStartedOkay()) {
try {
I2PD_JNI.stopDaemon();
} catch(Throwable tr) {
Log.e(TAG, "", tr);
}
setState(State.stopped);
}
}
private void processAssets() {
if (!assetsCopied) {
try {
assetsCopied = true;
File holderFile = new File(i2pdpath, "assets.ready");
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
StringBuilder text = new StringBuilder();
if (holderFile.exists()) {
try { // if holder file exists, read assets version string
FileReader fileReader = new FileReader(holderFile);
try {
BufferedReader br = new BufferedReader(fileReader);
try {
String line;
while ((line = br.readLine()) != null) {
text.append(line);
}
}finally {
try {
br.close();
} catch (IOException e) {
Log.e(TAG, "", e);
}
}
} finally {
try {
fileReader.close();
} catch (IOException e) {
Log.e(TAG, "", e);
}
}
} catch (IOException e) {
Log.e(TAG, "", e);
}
}
// if version differs from current app version or null, try to delete certificates folder
if (!text.toString().contains(versionName))
try {
boolean deleteResult = holderFile.delete();
if (!deleteResult)
Log.e(TAG, "holderFile.delete() returned " + deleteResult + ", absolute path='" + holderFile.getAbsolutePath() + "'");
File certPath = new File(i2pdpath, "certificates");
deleteRecursive(certPath);
}
catch (Throwable tr) {
Log.e(TAG, "", tr);
}
// copy assets. If processed file exists, it won't be overwritten
copyAsset("addressbook");
copyAsset("certificates");
copyAsset("tunnels.d");
copyAsset("i2pd.conf");
copyAsset("subscriptions.txt");
copyAsset("tunnels.conf");
// update holder file about successful copying
FileWriter writer = new FileWriter(holderFile);
try {
writer.append(versionName);
} finally {
try {
writer.close();
} catch (IOException e) {
Log.e(TAG,"on writer close", e);
}
}
}
catch (Throwable tr)
{
Log.e(TAG,"on assets copying", tr);
}
}
}
/**
* Copy the asset at the specified path to this app's data directory. If the
* asset is a directory, its contents are also copied.
*
* @param path
* Path to asset, relative to app's assets directory.
*/
private void copyAsset(String path) {
// If we have a directory, we make it and recurse. If a file, we copy its
// contents.
try {
String[] contents = assetManager.list(path);
// The documentation suggests that list throws an IOException, but doesn't
// say under what conditions. It'd be nice if it did so when the path was
// to a file. That doesn't appear to be the case. If the returned array is
// null or has 0 length, we assume the path is to a file. This means empty
// directories will get turned into files.
if (contents == null || contents.length == 0) {
copyFileAsset(path);
return;
}
// Make the directory.
File dir = new File(i2pdpath, path);
boolean result = dir.mkdirs();
Log.d(TAG, "dir.mkdirs() returned " + result);
// Recurse on the contents.
for (String entry : contents) {
copyAsset(path + '/' + entry);
}
} catch (IOException e) {
Log.e(TAG, "ex ignored for path='" + path + "'", e);
}
}
/**
* Copy the asset file specified by path to app's data directory. Assumes
* parent directories have already been created.
*
* @param path
* Path to asset, relative to app's assets directory.
*/
private void copyFileAsset(String path) {
File file = new File(i2pdpath, path);
if (!file.exists()) {
try {
try (InputStream in = assetManager.open(path)) {
try (OutputStream out = new FileOutputStream(file)) {
byte[] buffer = new byte[1024];
int read = in.read(buffer);
while (read != -1) {
out.write(buffer, 0, read);
read = in.read(buffer);
}
}
}
} catch (IOException e) {
Log.e(TAG, "", e);
}
}
}
private void deleteRecursive(File fileOrDirectory) {
if (fileOrDirectory.isDirectory()) {
File[] files = fileOrDirectory.listFiles();
if (files != null) {
for (File child : files) {
deleteRecursive(child);
}
}
}
boolean deleteResult = fileOrDirectory.delete();
if (!deleteResult)
Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'");
}
private void registerNetworkCallback(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) registerNetworkCallback0();
}
@TargetApi(Build.VERSION_CODES.M)
private void registerNetworkCallback0() {
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
.build();
NetworkStateCallbackImpl networkCallback = new NetworkStateCallbackImpl();
connectivityManager.registerNetworkCallback(request, networkCallback);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private static final class NetworkStateCallbackImpl extends ConnectivityManager.NetworkCallback {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
I2PD_JNI.onNetworkStateChanged(true);
Log.i(TAG, "NetworkCallback.onAvailable");
}
@Override
public void onLost(Network network) {
super.onLost(network);
I2PD_JNI.onNetworkStateChanged(false);
Log.i(TAG, " NetworkCallback.onLost");
}
}
}

188
android/src/org/purplei2p/i2pd/ForegroundService.java

@ -1,188 +0,0 @@ @@ -1,188 +0,0 @@
package org.purplei2p.i2pd;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import android.util.Log;
public class ForegroundService extends Service {
private static final String TAG="FgService";
private volatile boolean shown;
private static ForegroundService instance;
private static volatile DaemonWrapper daemon;
private static final Object initDeinitLock = new Object();
private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener =
new DaemonWrapper.StateUpdateListener() {
@Override
public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) {
updateNotificationText();
}
};
private void updateNotificationText() {
try {
synchronized (initDeinitLock) {
if (shown) cancelNotification();
showNotification();
}
} catch (Throwable tr) {
Log.e(TAG,"error ignored",tr);
}
}
private NotificationManager notificationManager;
// Unique Identification Number for the Notification.
// We use it on Notification start, and to cancel it.
private static final int NOTIFICATION = 1;
/**
* Class for clients to access. Because we know this service always
* runs in the same process as its clients, we don't need to deal with
* IPC.
*/
public class LocalBinder extends Binder {
ForegroundService getService() {
return ForegroundService.this;
}
}
public static void init(DaemonWrapper daemon) {
ForegroundService.daemon = daemon;
initCheck();
}
private static void initCheck() {
synchronized (initDeinitLock) {
if (instance != null && daemon != null) instance.setListener();
}
}
@Override
public void onCreate() {
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
instance = this;
initCheck();
}
private void setListener() {
daemon.addStateChangeListener(daemonStateUpdatedListener);
updateNotificationText();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ForegroundService", "Received start id " + startId + ": " + intent);
return START_STICKY;
}
@Override
public void onDestroy() {
cancelNotification();
deinitCheck();
instance=null;
}
public static void deinit() {
deinitCheck();
}
private static void deinitCheck() {
synchronized (initDeinitLock) {
if (daemon != null && instance != null)
daemon.removeStateChangeListener(instance.daemonStateUpdatedListener);
}
}
private void cancelNotification() {
synchronized (initDeinitLock) {
// Cancel the persistent notification.
notificationManager.cancel(NOTIFICATION);
stopForeground(true);
// Tell the user we stopped.
//Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
shown = false;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
/**
* Show a notification while this service is running.
*/
private void showNotification() {
synchronized (initDeinitLock) {
if (daemon != null) {
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(daemon.getState().getStatusStringResourceId());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, I2PDActivity.class), 0);
// If earlier version channel ID is not used
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : "";
// Set the info for the views that show in the notification panel.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
.setOngoing(true)
.setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon
if (Build.VERSION.SDK_INT >= 16)
builder = builder.setPriority(Notification.PRIORITY_DEFAULT);
if (Build.VERSION.SDK_INT >= 21)
builder = builder.setCategory(Notification.CATEGORY_SERVICE);
Notification notification = builder
.setTicker(text) // the status text
.setWhen(System.currentTimeMillis()) // the time stamp
.setContentTitle(getText(R.string.app_name)) // the label of the entry
.setContentText(text) // the contents of the entry
.setContentIntent(contentIntent) // The intent to send when the entry is clicked
.build();
// Send the notification.
//mNM.notify(NOTIFICATION, notification);
startForeground(NOTIFICATION, notification);
shown = true;
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
private synchronized String createNotificationChannel() {
String channelId = getString(R.string.app_name);
CharSequence channelName = "I2Pd service";
NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
//chan.setLightColor(Color.PURPLE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager service = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
if(service!=null)service.createNotificationChannel(chan);
else Log.e(TAG, "error: NOTIFICATION_SERVICE is null");
return channelId;
}
}

486
android/src/org/purplei2p/i2pd/I2PDActivity.java

@ -1,486 +0,0 @@ @@ -1,486 +0,0 @@
package org.purplei2p.i2pd;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Timer;
import java.util.TimerTask;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
// For future package update checking
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS;
public class I2PDActivity extends Activity {
private static final String TAG = "i2pdActvt";
private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000;
public static final String PACKAGE_URI_SCHEME = "package:";
private TextView textView;
//private ConfigParser parser = new ConfigParser(i2pdpath); // TODO
private static volatile DaemonWrapper daemon;
private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = new DaemonWrapper.StateUpdateListener() {
@Override
public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) {
updateStatusText();
}
};
private void updateStatusText() {
runOnUiThread(() -> {
try {
if (textView == null)
return;
Throwable tr = daemon.getLastThrowable();
if (tr!=null) {
textView.setText(throwableToString(tr));
return;
}
DaemonWrapper.State state = daemon.getState();
String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : "";
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr));
} catch (Throwable tr) {
Log.e(TAG,"error ignored",tr);
}
});
}
private static volatile long graceStartedMillis;
private static final Object graceStartedMillis_LOCK = new Object();
private Menu optionsMenu;
private static String formatGraceTimeRemaining() {
long remainingSeconds;
synchronized (graceStartedMillis_LOCK) {
remainingSeconds = Math.round(Math.max(0, graceStartedMillis + GRACEFUL_DELAY_MILLIS - System.currentTimeMillis()) / 1000.0D);
}
long remainingMinutes = (long)Math.floor(remainingSeconds / 60.0D);
long remSec = remainingSeconds - remainingMinutes * 60;
return remainingMinutes + ":" + (remSec / 10) + remSec % 10;
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate");
super.onCreate(savedInstanceState);
if (daemon==null) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
daemon = new DaemonWrapper(getAssets(), connectivityManager);
}
ForegroundService.init(daemon);
textView = new TextView(this);
setContentView(textView);
daemon.addStateChangeListener(daemonStateUpdatedListener);
daemonStateUpdatedListener.daemonStateUpdate(DaemonWrapper.State.uninitialized, daemon.getState());
// request permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
// set the app be foreground
doBindService();
final Timer gracefulQuitTimer = getGracefulQuitTimer();
if (gracefulQuitTimer != null) {
long gracefulStopAtMillis;
synchronized (graceStartedMillis_LOCK) {
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
}
rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis);
}
openBatteryOptimizationDialogIfNeeded();
}
@Override
protected void onDestroy() {
super.onDestroy();
textView = null;
ForegroundService.deinit();
daemon.removeStateChangeListener(daemonStateUpdatedListener);
//cancelGracefulStop0();
try {
doUnbindService();
} catch(Throwable tr) {
Log.e(TAG, "", tr);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if (requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
Log.e(TAG, "WR_EXT_STORAGE perm granted");
else {
Log.e(TAG, "WR_EXT_STORAGE perm declined, stopping i2pd");
i2pdStop();
//TODO must work w/o this perm, ask orignal
}
}
}
private void cancelGracefulStop0() {
Timer gracefulQuitTimer = getGracefulQuitTimer();
if (gracefulQuitTimer != null) {
gracefulQuitTimer.cancel();
setGracefulQuitTimer(null);
}
}
private CharSequence throwableToString(Throwable tr) {
StringWriter sw = new StringWriter(8192);
PrintWriter pw = new PrintWriter(sw);
tr.printStackTrace(pw);
pw.close();
return sw.toString();
}
// private LocalService mBoundService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
// mBoundService = ((LocalService.LocalBinder)service).getService();
// Tell the user about this for our demo.
// Toast.makeText(Binding.this, R.string.local_service_connected,
// Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
// mBoundService = null;
// Toast.makeText(Binding.this, R.string.local_service_disconnected,
// Toast.LENGTH_SHORT).show();
}
};
private static volatile boolean mIsBound;
private void doBindService() {
synchronized (I2PDActivity.class) {
if (mIsBound)
return;
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
}
private void doUnbindService() {
synchronized (I2PDActivity.class) {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.options_main, menu);
menu.findItem(R.id.action_battery_otimizations).setVisible(isBatteryOptimizationsOpenOsDialogApiAvailable());
this.optionsMenu = menu;
return true;
}
private boolean isBatteryOptimizationsOpenOsDialogApiAvailable() {
return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(id) {
case R.id.action_stop:
i2pdStop();
return true;
case R.id.action_graceful_stop:
synchronized (graceStartedMillis_LOCK) {
if (getGracefulQuitTimer() != null)
cancelGracefulStop();
else
i2pdGracefulStop();
}
return true;
case R.id.action_battery_otimizations:
onActionBatteryOptimizations();
return true;
case R.id.action_reload_tunnels_config:
onReloadTunnelsConfig();
return true;
case R.id.action_start_webview:
startActivity(new Intent(getApplicationContext(), WebConsoleActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
private void onActionBatteryOptimizations() {
if (isBatteryOptimizationsOpenOsDialogApiAvailable()) {
try {
startActivity(new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
} catch (ActivityNotFoundException e) {
Log.e(TAG, "BATT_OPTIM_DIALOG_ActvtNotFound", e);
Toast.makeText(this, R.string.os_version_does_not_support_battery_optimizations_show_os_dialog_api, Toast.LENGTH_SHORT).show();
}
}
}
private void onReloadTunnelsConfig() {
Log.d(TAG, "reloading tunnels");
daemon.reloadTunnelsConfigs();
Toast.makeText(this, R.string.tunnels_reloading, Toast.LENGTH_SHORT).show();
}
private void i2pdStop() {
cancelGracefulStop0();
new Thread(() -> {
Log.d(TAG, "stopping");
try {
daemon.stopDaemon();
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
quit(); //TODO make menu items for starting i2pd. On my Android, I need to reboot the OS to restart i2pd.
}, "stop").start();
}
private static volatile Timer gracefulQuitTimer;
private void i2pdGracefulStop() {
if (daemon.getState() == DaemonWrapper.State.stopped) {
Toast.makeText(this, R.string.already_stopped, Toast.LENGTH_SHORT).show();
return;
}
if (getGracefulQuitTimer() != null) {
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress, Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, R.string.graceful_stop_is_in_progress, Toast.LENGTH_SHORT).show();
new Thread(() -> {
try {
Log.d(TAG, "graceful stopping");
if (daemon.isStartedOkay()) {
daemon.stopAcceptingTunnels();
long gracefulStopAtMillis;
synchronized (graceStartedMillis_LOCK) {
graceStartedMillis = System.currentTimeMillis();
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
}
rescheduleGraceStop(null, gracefulStopAtMillis);
} else
i2pdStop();
} catch(Throwable tr) {
Log.e(TAG, "", tr);
}
}, "gracInit").start();
}
private void cancelGracefulStop()
{
cancelGracefulStop0();
new Thread(() -> {
try {
Log.d(TAG, "canceling graceful stop");
if (daemon.isStartedOkay()) {
daemon.startAcceptingTunnels();
runOnUiThread(() -> Toast.makeText(this, R.string.shutdown_canceled, Toast.LENGTH_SHORT).show());
} else
i2pdStop();
} catch(Throwable tr) {
Log.e(TAG, "", tr);
}
}, "gracCancel").start();
}
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) {
if (gracefulQuitTimerOld != null)
gracefulQuitTimerOld.cancel();
if(daemon.getTransitTunnelsCount() <= 0) { // no tunnels left
Log.d(TAG, "no transit tunnels left, stopping");
i2pdStop();
return;
}
final Timer gracefulQuitTimer = new Timer(true);
setGracefulQuitTimer(gracefulQuitTimer);
gracefulQuitTimer.schedule(new TimerTask() {
@Override
public void run() {
i2pdStop();
}
}, Math.max(0, gracefulStopAtMillis - System.currentTimeMillis()));
final TimerTask tickerTask = new TimerTask() {
@Override
public void run() {
updateStatusText();
}
};
gracefulQuitTimer.scheduleAtFixedRate(tickerTask, 0/*start delay*/, 1000/*millis period*/);
}
private static Timer getGracefulQuitTimer() {
return gracefulQuitTimer;
}
private void setGracefulQuitTimer(Timer gracefulQuitTimer) {
I2PDActivity.gracefulQuitTimer = gracefulQuitTimer;
runOnUiThread(()-> {
Menu menu = optionsMenu;
if (menu != null) {
MenuItem item = menu.findItem(R.id.action_graceful_stop);
if (item != null) {
synchronized (graceStartedMillis_LOCK) {
item.setTitle(getGracefulQuitTimer() != null ? R.string.action_cancel_graceful_stop : R.string.action_graceful_stop);
}
}
}
});
}
@SuppressLint("BatteryLife")
private void openBatteryOptimizationDialogIfNeeded() {
boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true);
Log.i(TAG, "BATT_OPTIM_questionEnabled==" + questionEnabled);
if (!isKnownIgnoringBatteryOptimizations()
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
&& questionEnabled) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.battery_optimizations_enabled);
builder.setMessage(R.string.battery_optimizations_enabled_dialog);
builder.setPositiveButton(R.string.continue_str, (dialog, which) -> {
try {
startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName())));
} catch (ActivityNotFoundException e) {
Log.e(TAG, "BATT_OPTIM_ActvtNotFound", e);
Toast.makeText(this, R.string.device_does_not_support_disabling_battery_optimizations, Toast.LENGTH_SHORT).show();
}
});
builder.setOnDismissListener(dialog -> setNeverAskForBatteryOptimizationsAgain());
final AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
}
private void setNeverAskForBatteryOptimizationsAgain() {
getPreferences().edit().putBoolean(getBatteryOptimizationPreferenceKey(), false).apply();
}
protected boolean isKnownIgnoringBatteryOptimizations() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
if (pm == null) {
Log.i(TAG, "BATT_OPTIM: POWER_SERVICE==null");
return false;
}
boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName());
Log.i(TAG, "BATT_OPTIM: ignoring==" + ignoring);
return ignoring;
} else {
Log.i(TAG, "BATT_OPTIM: old sdk version==" + Build.VERSION.SDK_INT);
return false;
}
}
protected SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
}
private String getBatteryOptimizationPreferenceKey() {
@SuppressLint("HardwareIds") String device = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
return "show_battery_optimization" + (device == null ? "" : device);
}
private void quit() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
finishAffinity();
} else {
//moveTaskToBack(true);
finish();
}
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
try {
daemon.stopDaemon();
} catch (Throwable tr) {
Log.e(TAG, "", tr);
}
System.exit(0);
}
}

170
android/src/org/purplei2p/i2pd/I2PDPermsAskerActivity.java

@ -1,170 +0,0 @@ @@ -1,170 +0,0 @@
package org.purplei2p.i2pd;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.lang.reflect.Method;
//dangerous perms, per https://developer.android.com/guide/topics/permissions/normal-permissions.html :
//android.permission.WRITE_EXTERNAL_STORAGE
public class I2PDPermsAskerActivity extends Activity {
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
private Button button_request_write_ext_storage_perms;
private TextView textview_retry;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//if less than Android 6, no runtime perms req system present
if (android.os.Build.VERSION.SDK_INT < 23) {
startMainActivity();
return;
}
setContentView(R.layout.activity_perms_asker);
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms);
textview_retry = (TextView) findViewById(R.id.textview_retry);
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
request_write_ext_storage_perms();
}
});
request_write_ext_storage_perms();
}
private void request_write_ext_storage_perms() {
textview_retry.setVisibility(TextView.GONE);
button_request_write_ext_storage_perms.setVisibility(Button.GONE);
Method methodCheckPermission;
Method method_shouldShowRequestPermissionRationale;
Method method_requestPermissions;
try {
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class);
method_shouldShowRequestPermissionRationale =
getClass().getMethod("shouldShowRequestPermissionRationale", String.class);
method_requestPermissions =
getClass().getMethod("requestPermissions", String[].class, int.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
Integer resultObj;
try {
resultObj = (Integer) methodCheckPermission.invoke(
this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
} catch (Throwable e) {
throw new RuntimeException(e);
}
if (resultObj != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
Boolean aBoolean;
try {
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (aBoolean) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
showExplanation();
} else {
// No explanation needed, we can request the permission.
try {
method_requestPermissions.invoke(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_WRITE_EXTERNAL_STORAGE);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} else startMainActivity();
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_WRITE_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
startMainActivity();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
textview_retry.setText(R.string.permDenied);
textview_retry.setVisibility(TextView.VISIBLE);
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE);
}
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
private void startMainActivity() {
startActivity(new Intent(this, I2PDActivity.class));
finish();
}
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
private void showExplanation() {
Intent intent = new Intent(this, I2PDPermsExplanationActivity.class);
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == SHOW_EXPLANATION_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// Request the permission
Method method_requestPermissions;
try {
method_requestPermissions =
getClass().getMethod("requestPermissions", String[].class, int.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
try {
method_requestPermissions.invoke(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_WRITE_EXTERNAL_STORAGE);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
finish(); //close the app
}
}
}
}

38
android/src/org/purplei2p/i2pd/I2PDPermsExplanationActivity.java

@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
package org.purplei2p.i2pd;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
public class I2PDPermsExplanationActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_perms_explanation);
ActionBar actionBar = getActionBar();
if(actionBar!=null)actionBar.setHomeButtonEnabled(false);
Button button_ok = (Button) findViewById(R.id.button_ok);
button_ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
returnFromActivity();
}
});
}
private void returnFromActivity() {
Intent data = new Intent();
Activity parent = getParent();
if (parent == null) {
setResult(Activity.RESULT_OK, data);
} else {
parent.setResult(Activity.RESULT_OK, data);
}
finish();
}
}

31
android/src/org/purplei2p/i2pd/I2PD_JNI.java

@ -1,31 +0,0 @@ @@ -1,31 +0,0 @@
package org.purplei2p.i2pd;
public class I2PD_JNI {
public static native String getABICompiledWith();
/**
* returns error info if failed
* returns "ok" if daemon initialized and started okay
*/
public static native String startDaemon();
//should only be called after startDaemon() success
public static native void stopDaemon();
public static native void stopAcceptingTunnels();
public static native void startAcceptingTunnels();
public static native void reloadTunnelsConfigs();
public static native void onNetworkStateChanged(boolean isConnected);
public static native void setDataDir(String jdataDir);
public static native int GetTransitTunnelsCount();
public static void loadLibraries() {
//System.loadLibrary("c++_shared");
System.loadLibrary("i2pd");
}
}

30
android/src/org/purplei2p/i2pd/NetworkStateChangeReceiver.java

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
package org.purplei2p.i2pd;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class NetworkStateChangeReceiver extends BroadcastReceiver {
private static final String TAG = "i2pd";
//api level 1
@Override
public void onReceive(final Context context, final Intent intent) {
Log.d(TAG,"Network state change");
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo();
boolean isConnected = activeNetworkInfo!=null && activeNetworkInfo.isConnected();
// https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html?hl=ru
// boolean isWiFi = activeNetworkInfo!=null && (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
I2PD_JNI.onNetworkStateChanged(isConnected);
} catch (Throwable tr) {
Log.d(TAG,"",tr);
}
}
}

67
android/src/org/purplei2p/i2pd/WebConsoleActivity.java

@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
package org.purplei2p.i2pd;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.Objects;
public class WebConsoleActivity extends Activity {
private WebView webView;
private SwipeRefreshLayout swipeRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_console);
Objects.requireNonNull(getActionBar()).setDisplayHomeAsUpEnabled(true);
webView = (WebView) findViewById(R.id.webview1);
webView.setWebViewClient(new WebViewClient());
final WebSettings webSettings = webView.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setJavaScriptEnabled(false);
webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
webView.reload();
}
}, 1000);
}
});
}
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
return true;
}
return false;
}
}

1
qt/.gitignore vendored

@ -1 +0,0 @@ @@ -1 +0,0 @@
/build*/

13
qt/i2pd_qt/.gitignore vendored

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
i2pd_qt.pro.user*
moc_*
ui_*
qrc_*
i2pd_qt
Makefile*
*.stash
object_script.*
i2pd_qt_plugin_import.cpp
i2pd_qt.pro.autosave*
build*
nohup.out

21
qt/i2pd_qt/AboutDialog.cpp

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
#include "AboutDialog.h"
#include "ui_AboutDialog.h"
#include <QDebug>
#include "version.h"
#include "BuildDateTimeQt.h"
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutDialog)
{
ui->setupUi(this);
ui->i2pdVersionLabel->setText(I2PD_VERSION);
ui->i2pVersionLabel->setText(I2P_VERSION);
ui->buildDateTimeLabel->setText(BUILD_DATE_TIME_QT);
ui->vcsCommitInfoLabel->setText(VCS_COMMIT_INFO);
}
AboutDialog::~AboutDialog()
{
delete ui;
}

22
qt/i2pd_qt/AboutDialog.h

@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
#ifndef ABOUTDIALOG_H
#define ABOUTDIALOG_H
#include <QDialog>
namespace Ui {
class AboutDialog;
}
class AboutDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutDialog(QWidget *parent = 0);
~AboutDialog();
private:
Ui::AboutDialog *ui;
};
#endif // ABOUTDIALOG_H

194
qt/i2pd_qt/AboutDialog.ui

@ -1,194 +0,0 @@ @@ -1,194 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AboutDialog</class>
<widget class="QDialog" name="AboutDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>199</height>
</rect>
</property>
<property name="windowTitle">
<string>About i2pd_qt</string>
</property>
<property name="windowIcon">
<iconset resource="i2pd.qrc">
<normaloff>:/icons/mask</normaloff>:/icons/mask</iconset>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>160</y>
<width>381</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>381</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;About i2pd_qt&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>i2pd Version:</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Build Date/Time:</string>
</property>
</widget>
<widget class="QLabel" name="i2pdVersionLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>40</y>
<width>241</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>I2PD_VERSION_LABEL</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>I2P Version:</string>
</property>
</widget>
<widget class="QLabel" name="i2pVersionLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>130</y>
<width>241</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>I2P_VERSION_LABEL</string>
</property>
</widget>
<widget class="QLabel" name="buildDateTimeLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>70</y>
<width>241</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>BUILD_DATE_TIME_LABEL</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Version Control:</string>
</property>
</widget>
<widget class="QLabel" name="vcsCommitInfoLabel">
<property name="geometry">
<rect>
<x>150</x>
<y>100</y>
<width>241</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>VCS_COMMIT_INFO_LABEL</string>
</property>
</widget>
</widget>
<resources>
<include location="i2pd.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AboutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

7
qt/i2pd_qt/BuildDateTimeQt.h

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
#ifndef BUILDDATETIMEQT_H
#define BUILDDATETIMEQT_H
#include <QString>
const QString BUILD_DATE_TIME_QT = QStringLiteral(__DATE__ " " __TIME__);
#endif // BUILDDATETIMEQT_H

220
qt/i2pd_qt/ClientTunnelPane.cpp

@ -1,220 +0,0 @@ @@ -1,220 +0,0 @@
#include "ClientTunnelPane.h"
#include "ClientContext.h"
#include "SignatureTypeComboboxFactory.h"
#include "QVBoxLayout"
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);
}
void ClientTunnelPane::deleteClientTunnelForm() {
TunnelPane::deleteTunnelForm();
delete clientTunnelNameGroupBox;
clientTunnelNameGroupBox=nullptr;
//gridLayoutWidget_2->deleteLater();
//gridLayoutWidget_2=nullptr;
}
int ClientTunnelPane::appendClientTunnelForm(
ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) {
ClientTunnelPane& ui = *this;
clientTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget);
clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox"));
//tunnel
gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox);
QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2);
tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox"));
tunnelTypeComboBox->addItem("Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT);
tunnelTypeComboBox->addItem("Socks", i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS);
tunnelTypeComboBox->addItem("Websocks", i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS);
tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY);
tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT);
int h=(7+4)*60;
gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h));
clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h));
{
const QString& type = tunnelConfig->getType();
int index=0;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)tunnelTypeComboBox->setCurrentIndex(index);
++index;
}
setupTunnelPane(tunnelConfig,
clientTunnelNameGroupBox,
gridLayoutWidget_2, tunnelTypeComboBox,
tunnelsFormGridLayoutWidget, tunnelsRow, height, h);
//this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10));
/*
std::string destination;
*/
//host
ui.horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.destinationLabel = new QLabel(gridLayoutWidget_2);
destinationLabel->setObjectName(QStringLiteral("destinationLabel"));
horizontalLayout_2->addWidget(destinationLabel);
ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2);
destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit"));
destinationLineEdit->setText(tunnelConfig->getdest().c_str());
QObject::connect(destinationLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(destinationLineEdit);
ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(destinationHorizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
/*
* int port;
*/
int gridIndex = 2;
{
int port = tunnelConfig->getport();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.portLabel = new QLabel(gridLayoutWidget_2);
portLabel->setObjectName(QStringLiteral("portLabel"));
horizontalLayout_2->addWidget(portLabel);
ui.portLineEdit = new QLineEdit(gridLayoutWidget_2);
portLineEdit->setObjectName(QStringLiteral("portLineEdit"));
portLineEdit->setText(QString::number(port));
portLineEdit->setMaximumWidth(80);
QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(portLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
/*
* std::string keys;
*/
{
std::string keys = tunnelConfig->getkeys();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.keysLabel = new QLabel(gridLayoutWidget_2);
keysLabel->setObjectName(QStringLiteral("keysLabel"));
horizontalLayout_2->addWidget(keysLabel);
ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2);
keysLineEdit->setObjectName(QStringLiteral("keysLineEdit"));
keysLineEdit->setText(keys.c_str());
QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(keysLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
/*
* std::string address;
*/
{
std::string address = tunnelConfig->getaddress();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.addressLabel = new QLabel(gridLayoutWidget_2);
addressLabel->setObjectName(QStringLiteral("addressLabel"));
horizontalLayout_2->addWidget(addressLabel);
ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2);
addressLineEdit->setObjectName(QStringLiteral("addressLineEdit"));
addressLineEdit->setText(address.c_str());
QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(addressLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
/*
int destinationPort;
i2p::data::SigningKeyType sigType;
*/
{
int destinationPort = tunnelConfig->getdestinationPort();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.destinationPortLabel = new QLabel(gridLayoutWidget_2);
destinationPortLabel->setObjectName(QStringLiteral("destinationPortLabel"));
horizontalLayout_2->addWidget(destinationPortLabel);
ui.destinationPortLineEdit = new QLineEdit(gridLayoutWidget_2);
destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit"));
destinationPortLineEdit->setText(QString::number(destinationPort));
destinationPortLineEdit->setMaximumWidth(80);
QObject::connect(destinationPortLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(destinationPortLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
int cryptoType = tunnelConfig->getcryptoType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2);
cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel"));
horizontalLayout_2->addWidget(cryptoTypeLabel);
ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2);
cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit"));
cryptoTypeLineEdit->setText(QString::number(cryptoType));
cryptoTypeLineEdit->setMaximumWidth(80);
QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(cryptoTypeLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.sigTypeLabel = new QLabel(gridLayoutWidget_2);
sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel"));
horizontalLayout_2->addWidget(sigTypeLabel);
ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType);
sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox"));
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);
}
{
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
appendControlsForI2CPParameters(i2cpParameters, gridIndex);
}
retranslateClientTunnelForm(ui);
tunnelGridLayout->invalidate();
return h;
}
ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;}
ClientTunnelPane* ClientTunnelPane::asClientTunnelPane(){return this;}

126
qt/i2pd_qt/ClientTunnelPane.h

@ -1,126 +0,0 @@ @@ -1,126 +0,0 @@
#ifndef CLIENTTUNNELPANE_H
#define CLIENTTUNNELPANE_H
#include "QGridLayout"
#include "QVBoxLayout"
#include "TunnelPane.h"
class ClientTunnelConfig;
class ServerTunnelPane;
class TunnelPane;
class ClientTunnelPane : public TunnelPane {
Q_OBJECT
public:
ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow);
virtual ~ClientTunnelPane(){}
virtual ServerTunnelPane* asServerTunnelPane();
virtual ClientTunnelPane* asClientTunnelPane();
int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget,
int tunnelsRow, int height);
void deleteClientTunnelForm();
private:
QGroupBox *clientTunnelNameGroupBox;
//tunnel
QWidget *gridLayoutWidget_2;
//destination
QHBoxLayout *horizontalLayout_2;
QLabel *destinationLabel;
QLineEdit *destinationLineEdit;
QSpacerItem *destinationHorizontalSpacer;
//port
QLabel * portLabel;
QLineEdit * portLineEdit;
//keys
QLabel * keysLabel;
QLineEdit * keysLineEdit;
//address
QLabel * addressLabel;
QLineEdit * addressLineEdit;
//destinationPort
QLabel * destinationPortLabel;
QLineEdit * destinationPortLineEdit;
//sigType
QLabel * sigTypeLabel;
QComboBox * sigTypeComboBox;
//cryptoType
QLabel * cryptoTypeLabel;
QLineEdit * cryptoTypeLineEdit;
protected slots:
virtual void setGroupBoxTitle(const QString & title);
private:
void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) {
typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0));
destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0));
portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0));
cryptoTypeLabel->setText(QApplication::translate("cltTunForm", "Crypto type:", 0));
keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0));
destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0));
addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0));
sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0));
}
protected:
virtual bool applyDataFromUIToTunnelConfig() {
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
if(!ok)return false;
ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig();
assert(ctc!=nullptr);
if(!isValidSingleLine(destinationLineEdit))return false;
if(!isValidSingleLine(portLineEdit))return false;
if(!isValidSingleLine(cryptoTypeLineEdit))return false;
if(!isValidSingleLine(keysLineEdit))return false;
if(!isValidSingleLine(addressLineEdit))return false;
if(!isValidSingleLine(destinationPortLineEdit))return false;
//destination
ctc->setdest(destinationLineEdit->text().toStdString());
auto portStr=portLineEdit->text();
int portInt=portStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit);
return false;
}
ctc->setport(portInt);
auto cryptoTypeStr=cryptoTypeLineEdit->text();
int cryptoTypeInt=cryptoTypeStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit);
return false;
}
ctc->setcryptoType(cryptoTypeInt);
ctc->setkeys(keysLineEdit->text().toStdString());
ctc->setaddress(addressLineEdit->text().toStdString());
auto dportStr=destinationPortLineEdit->text();
int dportInt=dportStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad destinationPort, must be int.")+" "+cannotSaveSettings,destinationPortLineEdit);
return false;
}
ctc->setdestinationPort(dportInt);
ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));
return true;
}
};
#endif // CLIENTTUNNELPANE_H

195
qt/i2pd_qt/DaemonQT.cpp

@ -1,195 +0,0 @@ @@ -1,195 +0,0 @@
#include <memory>
#include "DaemonQT.h"
#include "Daemon.h"
#include "mainwindow.h"
#include "Log.h"
#include <QMessageBox>
#include <QApplication>
#include <QMutexLocker>
#include <QThread>
//#define DEBUG_WITH_DEFAULT_LOGGING (1)
namespace i2p
{
namespace qt
{
Worker::Worker (DaemonQTImpl& daemon):
m_Daemon (daemon)
{
}
void Worker::startDaemon()
{
qDebug("Performing daemon start...");
//try{
m_Daemon.start();
qDebug("Daemon started.");
emit resultReady(false, "");
/*}catch(std::exception ex){
emit resultReady(true, ex.what());
}catch(...){
emit resultReady(true, QObject::tr("Error: unknown exception"));
}*/
}
void Worker::restartDaemon()
{
qDebug("Performing daemon restart...");
//try{
m_Daemon.restart();
qDebug("Daemon restarted.");
emit resultReady(false, "");
/*}catch(std::exception ex){
emit resultReady(true, ex.what());
}catch(...){
emit resultReady(true, QObject::tr("Error: unknown exception"));
}*/
}
void Worker::stopDaemon() {
qDebug("Performing daemon stop...");
//try{
m_Daemon.stop();
qDebug("Daemon stopped.");
emit resultReady(false, "");
/*}catch(std::exception ex){
emit resultReady(true, ex.what());
}catch(...){
emit resultReady(true, QObject::tr("Error: unknown exception"));
}*/
}
Controller::Controller(DaemonQTImpl& daemon):
m_Daemon (daemon)
{
Worker *worker = new Worker (m_Daemon);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
Controller::~Controller()
{
qDebug("Closing and waiting for daemon worker thread...");
workerThread.quit();
workerThread.wait();
qDebug("Waiting for daemon worker thread finished.");
if(m_Daemon.isRunning())
{
qDebug("Stopping the daemon...");
m_Daemon.stop();
qDebug("Stopped the daemon.");
}
}
DaemonQTImpl::DaemonQTImpl ():
mutex(nullptr), m_IsRunning(nullptr), m_RunningChangedCallback(nullptr)
{
}
DaemonQTImpl::~DaemonQTImpl ()
{
delete mutex;
}
bool DaemonQTImpl::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream)
{
mutex=new QMutex(QMutex::Recursive);
setRunningCallback(0);
m_IsRunning=false;
return Daemon.init(argc,argv,logstream);
}
void DaemonQTImpl::start()
{
QMutexLocker locker(mutex);
setRunning(true);
Daemon.start();
}
void DaemonQTImpl::stop()
{
QMutexLocker locker(mutex);
Daemon.stop();
setRunning(false);
}
void DaemonQTImpl::restart()
{
QMutexLocker locker(mutex);
stop();
start();
}
void DaemonQTImpl::setRunningCallback(runningChangedCallback cb)
{
m_RunningChangedCallback = cb;
}
bool DaemonQTImpl::isRunning()
{
return m_IsRunning;
}
void DaemonQTImpl::setRunning(bool newValue)
{
bool oldValue = m_IsRunning;
if(oldValue!=newValue)
{
m_IsRunning = newValue;
if(m_RunningChangedCallback)
m_RunningChangedCallback();
}
}
int RunQT (int argc, char* argv[])
{
QApplication app(argc, argv);
int result;
{
std::shared_ptr<std::iostream> logstreamptr=
#ifdef DEBUG_WITH_DEFAULT_LOGGING
nullptr
#else
std::make_shared<std::stringstream>()
#endif
;
//TODO move daemon init deinit to a bg thread
DaemonQTImpl daemon;
if(logstreamptr) (*logstreamptr) << "Initialising the daemon..." << std::endl;
bool daemonInitSuccess = daemon.init(argc, argv, logstreamptr);
if(!daemonInitSuccess)
{
QMessageBox::critical(0, "Error", "Daemon init failed");
return 1;
}
LogPrint(eLogDebug, "Initialised, creating the main window...");
MainWindow w(logstreamptr);
LogPrint(eLogDebug, "Before main window.show()...");
w.show ();
{
i2p::qt::Controller daemonQtController(daemon);
w.setI2PController(&daemonQtController);
LogPrint(eLogDebug, "Starting the daemon...");
emit daemonQtController.startDaemon();
//daemon.start ();
LogPrint(eLogDebug, "Starting GUI event loop...");
result = app.exec();
//daemon.stop ();
}
}
//QMessageBox::information(&w, "Debug", "demon stopped");
LogPrint(eLogDebug, "Exiting the application");
return result;
}
}
}

88
qt/i2pd_qt/DaemonQT.h

@ -1,88 +0,0 @@ @@ -1,88 +0,0 @@
#ifndef DAEMONQT_H
#define DAEMONQT_H
#include <memory>
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QMessageBox>
namespace i2p
{
namespace qt
{
class DaemonQTImpl
{
public:
DaemonQTImpl ();
~DaemonQTImpl ();
typedef void (*runningChangedCallback)();
/**
* @brief init
* @param argc
* @param argv
* @return success
*/
bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
void start();
void stop();
void restart();
void setRunningCallback(runningChangedCallback cb);
bool isRunning();
private:
void setRunning(bool running);
void showError(std::string errorMsg);
private:
QMutex* mutex;
bool m_IsRunning;
runningChangedCallback m_RunningChangedCallback;
};
class Worker : public QObject
{
Q_OBJECT
public:
Worker (DaemonQTImpl& daemon);
private:
DaemonQTImpl& m_Daemon;
public slots:
void startDaemon();
void restartDaemon();
void stopDaemon();
signals:
void resultReady(bool failed, QString failureMessage);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller(DaemonQTImpl& daemon);
~Controller();
private:
DaemonQTImpl& m_Daemon;
public slots:
void handleResults(bool failed, QString failureMessage){
if(failed){
QMessageBox::critical(0, QObject::tr("Error"), failureMessage);
}
}
signals:
void startDaemon();
void stopDaemon();
void restartDaemon();
};
}
}
#endif // DAEMONQT_H

3
qt/i2pd_qt/DelayedSaveManager.cpp

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
#include "DelayedSaveManager.h"
DelayedSaveManager::DelayedSaveManager(){}

26
qt/i2pd_qt/DelayedSaveManager.h

@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
#ifndef DELAYEDSAVEMANAGER_H
#define DELAYEDSAVEMANAGER_H
#include "Saver.h"
#include "I2pdQtTypes.h"
class DelayedSaveManager
{
public:
DelayedSaveManager();
virtual void setSaver(Saver* saver)=0;
typedef unsigned int DATA_SERIAL_TYPE;
virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus)=0;
//returns false iff save failed
virtual bool appExiting()=0;
virtual FocusEnum getFocusOn()=0;
virtual std::string& getTunnelNameToFocus()=0;
virtual QWidget* getWidgetToFocus()=0;
};
#endif // DELAYEDSAVEMANAGER_H

140
qt/i2pd_qt/DelayedSaveManagerImpl.cpp

@ -1,140 +0,0 @@ @@ -1,140 +0,0 @@
#include "DelayedSaveManagerImpl.h"
#include <assert.h>
DelayedSaveManagerImpl::DelayedSaveManagerImpl() :
widgetToFocus(nullptr),
saver(nullptr),
lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL),
lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP),
exiting(false),
thread(new DelayedSaveThread(this))
{
}
void DelayedSaveManagerImpl::setSaver(Saver* saver) {
this->saver = saver;
}
void DelayedSaveManagerImpl::start() {
thread->start();
}
bool DelayedSaveManagerImpl::isSaverValid() {
return saver != nullptr;
}
void DelayedSaveManagerImpl::delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus) {
if(lastDataSerialSeen==dataSerial)return;
this->reloadAfterSave = reloadAfterSave;
this->focusOn = focusOn;
this->tunnelNameToFocus = tunnelNameToFocus;
this->widgetToFocus = widgetToFocus;
lastDataSerialSeen=dataSerial;
assert(isSaverValid());
TIMESTAMP_TYPE now = getTime();
TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS;
if(now < wakeTime) {
//defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS
thread->deferSaveUntil(wakeTime);
return;
}
lastSaveStartedTimestamp = now;
thread->startSavingNow();
}
bool DelayedSaveManagerImpl::appExiting() {
exiting=true;
thread->wakeThreadAndJoinThread();
assert(isSaverValid());
saver->save(false, FocusEnum::noFocus);
return true;
}
DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_):
delayedSaveManagerImpl(delayedSaveManagerImpl_),
mutex(new QMutex()),
waitCondition(new QWaitCondition()),
saveNow(false),
defer(false)
{
mutex->lock();
}
DelayedSaveThread::~DelayedSaveThread(){
mutex->unlock();
delete mutex;
delete waitCondition;
}
void DelayedSaveThread::run() {
forever {
if(delayedSaveManagerImpl->isExiting())return;
waitCondition->wait(mutex, WAIT_TIME_MILLIS);
if(delayedSaveManagerImpl->isExiting())return;
Saver* saver = delayedSaveManagerImpl->getSaver();
assert(saver!=nullptr);
if(saveNow) {
saveNow = false;
const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn();
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus();
QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus();
saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus);
continue;
}
if(defer) {
defer=false;
#define max(a,b) (((a)>(b))?(a):(b))
forever {
TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime();
TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0);
if(millisToWait>0) {
waitCondition->wait(mutex, millisToWait);
if(delayedSaveManagerImpl->isExiting())return;
continue;
}
const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn();
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus();
QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus();
saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus);
break; //break inner loop
}
}
}
}
void DelayedSaveThread::wakeThreadAndJoinThread() {
waitCondition->wakeAll();
quit();
wait();//join //"similar to the POSIX pthread_join()"
}
DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() {
return QDateTime::currentMSecsSinceEpoch();
}
void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) {
wakeTime = wakeTime_;
defer = true;
waitCondition->wakeAll();
}
void DelayedSaveThread::startSavingNow() {
//mutex->lock();
saveNow=true;
waitCondition->wakeAll();
//mutex->unlock();
}
DelayedSaveManagerImpl::~DelayedSaveManagerImpl() {
thread->wakeThreadAndJoinThread();
delete thread;
}
bool DelayedSaveManagerImpl::isExiting() {
return exiting;
}
Saver* DelayedSaveManagerImpl::getSaver() {
return saver;
}

84
qt/i2pd_qt/DelayedSaveManagerImpl.h

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
#ifndef DELAYEDSAVEMANAGERIMPL_H
#define DELAYEDSAVEMANAGERIMPL_H
#include <QObject>
#include <QThread>
#include <QWaitCondition>
#include <QMutex>
#include <QDateTime>
#include "I2pdQtTypes.h"
#include "DelayedSaveManager.h"
#include "Saver.h"
class DelayedSaveManagerImpl;
class Saver;
class DelayedSaveThread : public QThread {
Q_OBJECT
public:
static constexpr unsigned long WAIT_TIME_MILLIS = 1000L;
typedef qint64 TIMESTAMP_TYPE;
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0;
DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl);
virtual ~DelayedSaveThread();
void run() override;
void deferSaveUntil(TIMESTAMP_TYPE wakeTime);
void startSavingNow();
void wakeThreadAndJoinThread();
private:
DelayedSaveManagerImpl* delayedSaveManagerImpl;
QMutex* mutex;
QWaitCondition* waitCondition;
volatile bool saveNow;
volatile bool defer;
volatile TIMESTAMP_TYPE wakeTime;
};
class DelayedSaveManagerImpl : public DelayedSaveManager {
FocusEnum focusOn;
std::string tunnelNameToFocus;
QWidget* widgetToFocus;
bool reloadAfterSave;
public:
DelayedSaveManagerImpl();
virtual ~DelayedSaveManagerImpl();
virtual void setSaver(Saver* saver);
virtual void start();
virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus);
virtual bool appExiting();
typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE;
static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0;
bool isExiting();
Saver* getSaver();
static TIMESTAMP_TYPE getTime();
bool isReloadAfterSave() { return reloadAfterSave; }
FocusEnum getFocusOn() { return focusOn; }
std::string& getTunnelNameToFocus() { return tunnelNameToFocus; }
QWidget* getWidgetToFocus() { return widgetToFocus; }
private:
Saver* saver;
bool isSaverValid();
DATA_SERIAL_TYPE lastDataSerialSeen;
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP;
TIMESTAMP_TYPE lastSaveStartedTimestamp;
bool exiting;
DelayedSaveThread* thread;
void wakeThreadAndJoinThread();
};
#endif // DELAYEDSAVEMANAGERIMPL_H

7
qt/i2pd_qt/I2pdQtTypes.h

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
#ifndef I2PDQTTYPES_H
#define I2PDQTTYPES_H
enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage };
enum FocusEnum { noFocus, focusOnTunnelName, focusOnWidget };
#endif // I2PDQTTYPES_H

12
qt/i2pd_qt/I2pdQtUtil.cpp

@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
#include "I2pdQtUtil.h"
bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow) {
bool correct = !widget->text().contains(QRegularExpression("[\r\n]"), nullptr);
if(!correct) {
mainWindow->highlightWrongInput(
QApplication::tr("Single line input expected, but it's multiline"),
inputPage,
widget);
}
return correct;
}

9
qt/i2pd_qt/I2pdQtUtil.h

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
#ifndef I2pdQtUtil_H
#define I2pdQtUtil_H
class QLineEdit;
#include "mainwindow.h"
bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow);
#endif // I2pdQtUtil_H

2
qt/i2pd_qt/MainWindowItems.cpp

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
#include "MainWindowItems.h"

17
qt/i2pd_qt/MainWindowItems.h

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
#ifndef MAINWINDOWITEMS_H
#define MAINWINDOWITEMS_H
#include <QString>
#include <QLineEdit>
#include <QPushButton>
#include <QComboBox>
#include <QCheckBox>
#include <sstream>
#include <functional>
#include "mainwindow.h"
class MainWindow;
#endif // MAINWINDOWITEMS_H

3
qt/i2pd_qt/README.md

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
# Build Requirements
* Qt 5 is necessary (because Qt4 lacks QtWidgets/ folder)

6
qt/i2pd_qt/Saver.cpp

@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
#include "Saver.h"
Saver::Saver()
{
}

25
qt/i2pd_qt/Saver.h

@ -1,25 +0,0 @@ @@ -1,25 +0,0 @@
#ifndef SAVER_H
#define SAVER_H
#include <string>
#include <QObject>
#include <QString>
class QWidget;
#include "I2pdQtTypes.h"
class Saver : public QObject
{
Q_OBJECT
public:
Saver();
//FocusEnum::focusNone iff failures //??? wtf
virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus="", QWidget* widgetToFocus=nullptr)=0;
signals:
void reloadTunnelsConfigAndUISignal(const QString);
};
#endif // SAVER_H

81
qt/i2pd_qt/SaverImpl.cpp

@ -1,81 +0,0 @@ @@ -1,81 +0,0 @@
#include "SaverImpl.h"
#include <fstream>
#include <assert.h>
#include <sstream>
#include "QList"
#include "QString"
#include "mainwindow.h"
SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_) :
configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_)
{}
SaverImpl::~SaverImpl() {}
bool SaverImpl::save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus) {
//save main config
{
std::stringstream out;
for(QList<MainWindowItem*>::iterator it = configItems->begin(); it!= configItems->end(); ++it) {
MainWindowItem* item = *it;
item->saveToStringStream(out);
}
using namespace std;
QString backup=confpath+"~";
if(QFile::exists(backup)) QFile::remove(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();
outfile.close();
}
//save tunnels config
{
std::stringstream out;
for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs->begin(); it!=tunnelConfigs->end(); ++it) {
//const std::string& name = it->first;
TunnelConfig* tunconf = it->second;
tunconf->saveHeaderToStringStream(out);
tunconf->saveToStringStream(out);
tunconf->saveI2CPParametersToStringStream(out);
}
using namespace std;
QString backup=tunconfpath+"~";
if(QFile::exists(backup)) QFile::remove(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();
outfile.close();
}
if(reloadAfterSave) {
//reload saved configs
#if 0
i2p::client::context.ReloadConfig();
#endif
if(reloadAfterSave) emit reloadTunnelsConfigAndUISignal(focusOn==FocusEnum::focusOnTunnelName?QString::fromStdString(tunnelNameToFocus):"");
}
return true;
}
void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; }
void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; }
/*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) {
this->focusOnTunnel=focusOnTunnel;
this->tunnelNameToFocus=tunnelNameToFocus;
}*/

33
qt/i2pd_qt/SaverImpl.h

@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
#ifndef SAVERIMPL_H
#define SAVERIMPL_H
#include <map>
#include <string>
#include <QObject>
#include "QList"
#include "mainwindow.h"
#include "TunnelConfig.h"
#include "Saver.h"
class MainWindowItem;
class TunnelConfig;
class SaverImpl : public Saver
{
public:
SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_);
virtual ~SaverImpl();
virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus);
void setConfPath(QString& confpath_);
void setTunnelsConfPath(QString& tunconfpath_);
private:
QList<MainWindowItem*> * configItems;
std::map<std::string,TunnelConfig*>* tunnelConfigs;
QString confpath;
QString tunconfpath;
MainWindow* mainWindowPtr;
};
#endif // SAVERIMPL_H

278
qt/i2pd_qt/ServerTunnelPane.cpp

@ -1,278 +0,0 @@ @@ -1,278 +0,0 @@
#include "ServerTunnelPane.h"
#include "ClientContext.h"
#include "SignatureTypeComboboxFactory.h"
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);
}
int ServerTunnelPane::appendServerTunnelForm(
ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) {
ServerTunnelPane& ui = *this;
serverTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget);
serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox"));
//tunnel
gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox);
QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2);
tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox"));
tunnelTypeComboBox->addItem("Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER);
tunnelTypeComboBox->addItem("HTTP", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP);
tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC);
tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER);
int h=19*60;
gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h));
serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h));
{
const QString& type = tunnelConfig->getType();
int index=0;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC)tunnelTypeComboBox->setCurrentIndex(index);
++index;
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER)tunnelTypeComboBox->setCurrentIndex(index);
++index;
}
setupTunnelPane(tunnelConfig,
serverTunnelNameGroupBox,
gridLayoutWidget_2, tunnelTypeComboBox,
tunnelsFormGridLayoutWidget, tunnelsRow, height, h);
//this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10));
//host
ui.horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.hostLabel = new QLabel(gridLayoutWidget_2);
hostLabel->setObjectName(QStringLiteral("hostLabel"));
horizontalLayout_2->addWidget(hostLabel);
ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2);
hostLineEdit->setObjectName(QStringLiteral("hostLineEdit"));
hostLineEdit->setText(tunnelConfig->gethost().c_str());
QObject::connect(hostLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(hostLineEdit);
ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(hostHorizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
int gridIndex = 2;
{
int port = tunnelConfig->getport();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.portLabel = new QLabel(gridLayoutWidget_2);
portLabel->setObjectName(QStringLiteral("portLabel"));
horizontalLayout_2->addWidget(portLabel);
ui.portLineEdit = new QLineEdit(gridLayoutWidget_2);
portLineEdit->setObjectName(QStringLiteral("portLineEdit"));
portLineEdit->setText(QString::number(port));
portLineEdit->setMaximumWidth(80);
QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(portLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
std::string keys = tunnelConfig->getkeys();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.keysLabel = new QLabel(gridLayoutWidget_2);
keysLabel->setObjectName(QStringLiteral("keysLabel"));
horizontalLayout_2->addWidget(keysLabel);
ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2);
keysLineEdit->setObjectName(QStringLiteral("keysLineEdit"));
keysLineEdit->setText(keys.c_str());
QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(keysLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
int inPort = tunnelConfig->getinPort();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.inPortLabel = new QLabel(gridLayoutWidget_2);
inPortLabel->setObjectName(QStringLiteral("inPortLabel"));
horizontalLayout_2->addWidget(inPortLabel);
ui.inPortLineEdit = new QLineEdit(gridLayoutWidget_2);
inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit"));
inPortLineEdit->setText(QString::number(inPort));
inPortLineEdit->setMaximumWidth(80);
QObject::connect(inPortLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(inPortLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
std::string accessList = tunnelConfig->getaccessList();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.accessListLabel = new QLabel(gridLayoutWidget_2);
accessListLabel->setObjectName(QStringLiteral("accessListLabel"));
horizontalLayout_2->addWidget(accessListLabel);
ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2);
accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit"));
accessListLineEdit->setText(accessList.c_str());
QObject::connect(accessListLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(accessListLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
std::string hostOverride = tunnelConfig->gethostOverride();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.hostOverrideLabel = new QLabel(gridLayoutWidget_2);
hostOverrideLabel->setObjectName(QStringLiteral("hostOverrideLabel"));
horizontalLayout_2->addWidget(hostOverrideLabel);
ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2);
hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit"));
hostOverrideLineEdit->setText(hostOverride.c_str());
QObject::connect(hostOverrideLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(hostOverrideLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
std::string webIRCPass = tunnelConfig->getwebircpass();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.webIRCPassLabel = new QLabel(gridLayoutWidget_2);
webIRCPassLabel->setObjectName(QStringLiteral("webIRCPassLabel"));
horizontalLayout_2->addWidget(webIRCPassLabel);
ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2);
webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit"));
webIRCPassLineEdit->setText(webIRCPass.c_str());
QObject::connect(webIRCPassLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(webIRCPassLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
bool gzip = tunnelConfig->getgzip();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2);
gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox"));
gzipCheckBox->setChecked(gzip);
QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(gzipCheckBox);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.sigTypeLabel = new QLabel(gridLayoutWidget_2);
sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel"));
horizontalLayout_2->addWidget(sigTypeLabel);
ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType);
sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox"));
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);
}
{
std::string address = tunnelConfig->getaddress();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.addressLabel = new QLabel(gridLayoutWidget_2);
addressLabel->setObjectName(QStringLiteral("addressLabel"));
horizontalLayout_2->addWidget(addressLabel);
ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2);
addressLineEdit->setObjectName(QStringLiteral("addressLineEdit"));
addressLineEdit->setText(address.c_str());
QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(addressLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
bool isUniqueLocal = tunnelConfig->getisUniqueLocal();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2);
isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox"));
isUniqueLocalCheckBox->setChecked(isUniqueLocal);
QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(isUniqueLocalCheckBox);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
int cryptoType = tunnelConfig->getcryptoType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2);
cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel"));
horizontalLayout_2->addWidget(cryptoTypeLabel);
ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2);
cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit"));
cryptoTypeLineEdit->setText(QString::number(cryptoType));
cryptoTypeLineEdit->setMaximumWidth(80);
QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(cryptoTypeLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters();
appendControlsForI2CPParameters(i2cpParameters, gridIndex);
}
retranslateServerTunnelForm(ui);
tunnelGridLayout->invalidate();
return h;
}
void ServerTunnelPane::deleteServerTunnelForm() {
TunnelPane::deleteTunnelForm();
delete serverTunnelNameGroupBox;//->deleteLater();
serverTunnelNameGroupBox=nullptr;
//gridLayoutWidget_2->deleteLater();
//gridLayoutWidget_2=nullptr;
}
ServerTunnelPane* ServerTunnelPane::asServerTunnelPane(){return this;}
ClientTunnelPane* ServerTunnelPane::asClientTunnelPane(){return nullptr;}

183
qt/i2pd_qt/ServerTunnelPane.h

@ -1,183 +0,0 @@ @@ -1,183 +0,0 @@
#ifndef SERVERTUNNELPANE_H
#define SERVERTUNNELPANE_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QWidget>
#include "QVBoxLayout"
#include "QCheckBox"
#include "assert.h"
#include "TunnelPane.h"
#include "TunnelsPageUpdateListener.h"
class ServerTunnelConfig;
class ClientTunnelPane;
class ServerTunnelPane : public TunnelPane {
Q_OBJECT
public:
ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow);
virtual ~ServerTunnelPane(){}
virtual ServerTunnelPane* asServerTunnelPane();
virtual ClientTunnelPane* asClientTunnelPane();
int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget,
int tunnelsRow, int height);
void deleteServerTunnelForm();
private:
QGroupBox *serverTunnelNameGroupBox;
//tunnel
QWidget *gridLayoutWidget_2;
//host
QHBoxLayout *horizontalLayout_2;
QLabel *hostLabel;
QLineEdit *hostLineEdit;
QSpacerItem *hostHorizontalSpacer;
//port
QLabel * portLabel;
QLineEdit * portLineEdit;
//keys
QLabel * keysLabel;
QLineEdit * keysLineEdit;
//inPort
QLabel * inPortLabel;
QLineEdit * inPortLineEdit;
//cryptoType
QLabel * cryptoTypeLabel;
QLineEdit * cryptoTypeLineEdit;
//accessList
QLabel * accessListLabel;
QLineEdit * accessListLineEdit;
//hostOverride
QLabel * hostOverrideLabel;
QLineEdit * hostOverrideLineEdit;
//webIRCPass
QLabel * webIRCPassLabel;
QLineEdit * webIRCPassLineEdit;
//address
QLabel * addressLabel;
QLineEdit * addressLineEdit;
//gzip
QCheckBox * gzipCheckBox;
//isUniqueLocal
QCheckBox * isUniqueLocalCheckBox;
//sigType
QLabel * sigTypeLabel;
QComboBox * sigTypeComboBox;
protected slots:
virtual void setGroupBoxTitle(const QString & title);
private:
void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) {
typeLabel->setText(QApplication::translate("srvTunForm", "Server tunnel type:", 0));
hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0));
portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0));
keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0));
inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0));
cryptoTypeLabel->setText(QApplication::translate("srvTunForm", "Crypto type:", 0));
accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0));
hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0));
webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0));
addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0));
gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0));
isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0));
sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0));
}
protected:
virtual bool applyDataFromUIToTunnelConfig() {
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
bool ok=TunnelPane::applyDataFromUIToTunnelConfig();
if(!ok)return false;
ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig();
assert(stc!=nullptr);
if(!isValidSingleLine(hostLineEdit))return false;
if(!isValidSingleLine(portLineEdit))return false;
if(!isValidSingleLine(cryptoTypeLineEdit))return false;
if(!isValidSingleLine(keysLineEdit))return false;
if(!isValidSingleLine(inPortLineEdit))return false;
if(!isValidSingleLine(accessListLineEdit))return false;
if(!isValidSingleLine(hostOverrideLineEdit))return false;
if(!isValidSingleLine(webIRCPassLineEdit))return false;
if(!isValidSingleLine(addressLineEdit))return false;
stc->sethost(hostLineEdit->text().toStdString());
auto portStr=portLineEdit->text();
int portInt=portStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit);
return false;
}
stc->setport(portInt);
auto cryptoTypeStr=cryptoTypeLineEdit->text();
int cryptoTypeInt=cryptoTypeStr.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit);
return false;
}
stc->setcryptoType(cryptoTypeInt);
stc->setkeys(keysLineEdit->text().toStdString());
auto str=inPortLineEdit->text();
int inPortInt=str.toInt(&ok);
if(!ok){
highlightWrongInput(QApplication::tr("Bad inPort, must be int.")+" "+cannotSaveSettings,inPortLineEdit);
return false;
}
stc->setinPort(inPortInt);
stc->setaccessList(accessListLineEdit->text().toStdString());
stc->sethostOverride(hostOverrideLineEdit->text().toStdString());
stc->setwebircpass(webIRCPassLineEdit->text().toStdString());
stc->setaddress(addressLineEdit->text().toStdString());
stc->setgzip(gzipCheckBox->isChecked());
stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked());
stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox));
return true;
}
};
#endif // SERVERTUNNELPANE_H

2
qt/i2pd_qt/SignatureTypeComboboxFactory.cpp

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
#include "SignatureTypeComboboxFactory.h"

86
qt/i2pd_qt/SignatureTypeComboboxFactory.h

@ -1,86 +0,0 @@ @@ -1,86 +0,0 @@
#ifndef SIGNATURETYPECOMBOBOXFACTORY_H
#define SIGNATURETYPECOMBOBOXFACTORY_H
#include <QApplication>
#include <QComboBox>
#include <QWidget>
#include "Identity.h"
class SignatureTypeComboBoxFactory
{
static const QVariant createUserData(const uint16_t sigType) {
return QVariant::fromValue((uint)sigType);
}
static void addItem(QComboBox* signatureTypeCombobox, QString text, const uint16_t sigType) {
const QVariant userData = createUserData(sigType);
signatureTypeCombobox->addItem(text, userData);
}
public:
static uint16_t getSigType(const QVariant& var) {
return (uint16_t)var.toInt();
}
static void fillComboBox(QComboBox* signatureTypeCombobox, uint16_t selectedSigType) {
/*
<orignal> https://geti2p.net/spec/common-structures#certificate
<orignal> все коды перечислены
<Hypnosis> это таблица "The defined Signing Public Key types are:" ?
<orignal> да
see also: Identity.h line 55
*/
int index=0;
bool foundSelected=false;
using namespace i2p::data;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "DSA_SHA1", 0), SIGNING_KEY_TYPE_DSA_SHA1); //0
if(selectedSigType==SIGNING_KEY_TYPE_DSA_SHA1){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA256_P256", 0), SIGNING_KEY_TYPE_ECDSA_SHA256_P256); //1
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA256_P256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA384_P384", 0), SIGNING_KEY_TYPE_ECDSA_SHA384_P384); //2
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA384_P384){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA512_P521", 0), SIGNING_KEY_TYPE_ECDSA_SHA512_P521); //3
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA512_P521){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA256_2048", 0), SIGNING_KEY_TYPE_RSA_SHA256_2048); //4
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA256_2048){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA384_3072", 0), SIGNING_KEY_TYPE_RSA_SHA384_3072); //5
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA384_3072){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA512_4096", 0), SIGNING_KEY_TYPE_RSA_SHA512_4096); //6
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA512_4096){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7
if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph); //8
if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
// the following signature type should never appear in netid=2
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256); //9
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
++index;
if(!foundSelected){
addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype
signatureTypeCombobox->setCurrentIndex(index);
}
}
static QComboBox* createSignatureTypeComboBox(QWidget* parent, uint16_t selectedSigType) {
QComboBox* signatureTypeCombobox = new QComboBox(parent);
fillComboBox(signatureTypeCombobox, selectedSigType);
return signatureTypeCombobox;
}
};
#endif // SIGNATURETYPECOMBOBOXFACTORY_H

67
qt/i2pd_qt/TunnelConfig.cpp

@ -1,67 +0,0 @@ @@ -1,67 +0,0 @@
#include "TunnelConfig.h"
void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) {
out << "[" << name << "]\n"
<< "type=" << type.toStdString() << "\n";
}
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()) //todo #947
out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "="
<< i2cpParameters.getExplicitPeers().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_AUTH_TYPE << "="
<< i2cpParameters.get_i2cp_leaseSetAuthType().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_ENCRYPTION_TYPE << "="
<< i2cpParameters.get_i2cp_leaseSetEncType().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_PRIV_KEY << "="
<< i2cpParameters.get_i2cp_leaseSetPrivKey().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_LEASESET_TYPE << "="
<< i2cpParameters.get_i2cp_leaseSetType().toStdString() << "\n";
out << i2p::client::I2CP_PARAM_STREAMING_ANSWER_PINGS << "="
<< (i2cpParameters.get_i2p_streaming_answerPings() ? "true" : "false") << "\n";
out << i2p::client::I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY << "="
<< i2cpParameters.get_i2p_streaming_initialAckDelay().toStdString() << "\n";
out << "\n";
}
void ClientTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "address=" << address << "\n"
<< "port=" << port << "\n"
<< "destination=" << dest << "\n"
<< "destinationport=" << destinationPort << "\n"
<< "cryptoType=" << getcryptoType() << "\n"
<< "signaturetype=" << sigType << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
}
void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
out << "host=" << host << "\n"
<< "port=" << port << "\n"
<< "signaturetype=" << sigType << "\n"
<< "inport=" << inPort << "\n";
if(accessList.size()>0) { out << "accesslist=" << accessList << "\n"; }
out << "gzip=" << (gzip?"true":"false") << "\n"
<< "cryptoType=" << getcryptoType() << "\n"
<< "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n"
<< "address=" << address << "\n"
<< "hostoverride=" << hostOverride << "\n"
<< "webircpassword=" << webircpass << "\n";
if(!keys.empty()) out << "keys=" << keys << "\n";
}

260
qt/i2pd_qt/TunnelConfig.h

@ -1,260 +0,0 @@ @@ -1,260 +0,0 @@
#ifndef TUNNELCONFIG_H
#define TUNNELCONFIG_H
#include "QString"
#include <string>
#include "../../libi2pd_client/ClientContext.h"
#include "../../libi2pd/Destination.h"
#include "TunnelsPageUpdateListener.h"
class I2CPParameters{
QString inbound_length;//number of hops of an inbound tunnel. 3 by default; lower value is faster but dangerous
QString outbound_length;//number of hops of an outbound tunnel. 3 by default; lower value is faster but dangerous
QString inbound_quantity; //number of inbound tunnels. 5 by default
QString outbound_quantity; //number of outbound tunnels. 5 by default
QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building
QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset
QString i2p_streaming_initialAckDelay; //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
bool i2p_streaming_answerPings; //i2p.streaming.answerPings -- enable sending pongs. true by default
QString i2cp_leaseSetType; //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
QString i2cp_leaseSetEncType; //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
QString i2cp_leaseSetPrivKey; //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
QString i2cp_leaseSetAuthType; //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
public:
I2CPParameters(): inbound_length(),
outbound_length(),
inbound_quantity(),
outbound_quantity(),
crypto_tagsToSend(),
explicitPeers(),
i2p_streaming_initialAckDelay(),
i2p_streaming_answerPings(true),
i2cp_leaseSetType(),
i2cp_leaseSetEncType(),
i2cp_leaseSetPrivKey(),
i2cp_leaseSetAuthType() {}
const QString& getInbound_length(){return inbound_length;}
const QString& getOutbound_length(){return outbound_length;}
const QString& getInbound_quantity(){return inbound_quantity;}
const QString& getOutbound_quantity(){return outbound_quantity;}
const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;}
const QString& getExplicitPeers(){return explicitPeers;}
const QString& get_i2p_streaming_initialAckDelay(){return i2p_streaming_initialAckDelay;}
bool get_i2p_streaming_answerPings(){return i2p_streaming_answerPings;}
const QString& get_i2cp_leaseSetType(){return i2cp_leaseSetType;}
const QString& get_i2cp_leaseSetEncType(){return i2cp_leaseSetEncType;}
const QString& get_i2cp_leaseSetPrivKey(){return i2cp_leaseSetPrivKey;}
const QString& get_i2cp_leaseSetAuthType(){return i2cp_leaseSetAuthType;}
void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;}
void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;}
void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;}
void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;}
void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;}
void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;}
void set_i2p_streaming_initialAckDelay(QString i2p_streaming_initialAckDelay_){i2p_streaming_initialAckDelay=i2p_streaming_initialAckDelay_;}
void set_i2p_streaming_answerPings(bool i2p_streaming_answerPings_){i2p_streaming_answerPings=i2p_streaming_answerPings_;}
void set_i2cp_leaseSetType(QString i2cp_leaseSetType_){i2cp_leaseSetType=i2cp_leaseSetType_;}
void set_i2cp_leaseSetEncType(QString i2cp_leaseSetEncType_){i2cp_leaseSetEncType=i2cp_leaseSetEncType_;}
void set_i2cp_leaseSetPrivKey(QString i2cp_leaseSetPrivKey_){i2cp_leaseSetPrivKey=i2cp_leaseSetPrivKey_;}
void set_i2cp_leaseSetAuthType(QString i2cp_leaseSetAuthType_){i2cp_leaseSetAuthType=i2cp_leaseSetAuthType_;}
};
class ClientTunnelConfig;
class ServerTunnelConfig;
class TunnelPane;
class TunnelConfig {
/*
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
*/
QString type;
std::string name;
TunnelPane* tunnelPane;
int cryptoType;
public:
TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_, int cryptoType_):
type(type_), name(name_), cryptoType(cryptoType_), i2cpParameters(i2cpParameters_) {}
virtual ~TunnelConfig(){}
const QString& getType(){return type;}
const std::string& getName(){return name;}
int getcryptoType(){return cryptoType;}
void setType(const QString& type_){type=type_;}
void setName(const std::string& name_){name=name_;}
I2CPParameters& getI2cpParameters(){return i2cpParameters;}
void saveHeaderToStringStream(std::stringstream& out);
void saveI2CPParametersToStringStream(std::stringstream& out);
virtual void saveToStringStream(std::stringstream& out)=0;
virtual ClientTunnelConfig* asClientTunnelConfig()=0;
virtual ServerTunnelConfig* asServerTunnelConfig()=0;
void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;}
TunnelPane* getTunnelPane() {return tunnelPane;}
void setcryptoType(int cryptoType_){cryptoType=cryptoType_;}
private:
I2CPParameters i2cpParameters;
};
/*
# mandatory parameters:
std::string dest;
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
# optional parameters (may be omitted)
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);
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
# * keys -- our identity, if unset, will be generated on every startup,
# if set and file missing, keys will be generated and placed to this file
# * address -- local interface to bind
# * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512)
[somelabel]
type = client
address = 127.0.0.1
port = 6668
destination = irc.postman.i2p
keys = irc-keys.dat
*/
class ClientTunnelConfig : public TunnelConfig {
std::string dest;
int port;
std::string keys;
std::string address;
int destinationPort;
i2p::data::SigningKeyType sigType;
public:
ClientTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_,
std::string dest_,
int port_,
std::string keys_,
std::string address_,
int destinationPort_,
i2p::data::SigningKeyType sigType_,
int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_),
dest(dest_),
port(port_),
keys(keys_),
address(address_),
destinationPort(destinationPort_),
sigType(sigType_) {}
std::string& getdest(){return dest;}
int getport(){return port;}
std::string & getkeys(){return keys;}
std::string & getaddress(){return address;}
int getdestinationPort(){return destinationPort;}
i2p::data::SigningKeyType getsigType(){return sigType;}
void setdest(const std::string& dest_){dest=dest_;}
void setport(int port_){port=port_;}
void setkeys(const std::string & keys_){keys=keys_;}
void setaddress(const std::string & address_){address=address_;}
void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;}
void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;}
virtual void saveToStringStream(std::stringstream& out);
virtual ClientTunnelConfig* asClientTunnelConfig(){return this;}
virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;}
};
/*
# mandatory parameters:
# * host -- ip address of our service
# * port -- port of our service
# * keys -- file with LeaseSet of address in i2p
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS);
# optional parameters (may be omitted)
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
# * inport -- optional, i2p service port, if unset - the same as 'port'
# * accesslist -- comma-separated list of i2p addresses, allowed to connect
# every address is b32 without '.b32.i2p' part
[somelabel]
type = server
host = 127.0.0.1
port = 6667
keys = irc.dat
*/
class ServerTunnelConfig : public TunnelConfig {
std::string host;
int port;
std::string keys;
int inPort;
std::string accessList;
std::string hostOverride;
std::string webircpass;
bool gzip;
i2p::data::SigningKeyType sigType;
std::string address;
bool isUniqueLocal;
public:
ServerTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_,
std::string host_,
int port_,
std::string keys_,
int inPort_,
std::string accessList_,
std::string hostOverride_,
std::string webircpass_,
bool gzip_,
i2p::data::SigningKeyType sigType_,
std::string address_,
bool isUniqueLocal_,
int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_),
host(host_),
port(port_),
keys(keys_),
inPort(inPort_),
accessList(accessList_),
hostOverride(hostOverride_),
webircpass(webircpass_),
gzip(gzip_),
sigType(sigType_),
address(address_),
isUniqueLocal(isUniqueLocal_) {}
std::string& gethost(){return host;}
int getport(){return port;}
std::string& getkeys(){return keys;}
int getinPort(){return inPort;}
std::string& getaccessList(){return accessList;}
std::string& gethostOverride(){return hostOverride;}
std::string& getwebircpass(){return webircpass;}
bool getgzip(){return gzip;}
i2p::data::SigningKeyType getsigType(){return sigType;}
std::string& getaddress(){return address;}
bool getisUniqueLocal(){return isUniqueLocal;}
void sethost(const std::string& host_){host=host_;}
void setport(int port_){port=port_;}
void setkeys(const std::string& keys_){keys=keys_;}
void setinPort(int inPort_){inPort=inPort_;}
void setaccessList(const std::string& accessList_){accessList=accessList_;}
void sethostOverride(const std::string& hostOverride_){hostOverride=hostOverride_;}
void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;}
void setgzip(bool gzip_){gzip=gzip_;}
void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;}
void setaddress(const std::string& address_){address=address_;}
void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;}
virtual void saveToStringStream(std::stringstream& out);
virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;}
virtual ServerTunnelConfig* asServerTunnelConfig(){return this;}
};
#endif // TUNNELCONFIG_H

405
qt/i2pd_qt/TunnelPane.cpp

@ -1,405 +0,0 @@ @@ -1,405 +0,0 @@
#include "TunnelPane.h"
#include "QMessageBox"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "I2pdQtUtil.h"
TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_):
QObject(),
mainWindow(mainWindow_),
wrongInputPane(wrongInputPane_),
wrongInputLabel(wrongInputLabel_),
tunnelConfig(tunnelConfig_),
tunnelsPageUpdateListener(tunnelsPageUpdateListener_),
gridLayoutWidget_2(nullptr) {}
void TunnelPane::setupTunnelPane(
TunnelConfig* tunnelConfig,
QGroupBox *tunnelGroupBox,
QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox,
QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h) {
tunnelGroupBox->setGeometry(0, tunnelsFormGridLayoutWidget->height(), gridLayoutWidget_2->width(), h);
tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+h);
QObject::connect(tunnelTypeComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(updated()));
this->tunnelGroupBox=tunnelGroupBox;
gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2"));
this->gridLayoutWidget_2=gridLayoutWidget_2;
tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2);
tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout"));
tunnelGridLayout->setContentsMargins(10, 25, 10, 10);
tunnelGridLayout->setSpacing(5);
//header
QHBoxLayout *headerHorizontalLayout = new QHBoxLayout();
headerHorizontalLayout->setObjectName(QStringLiteral("headerHorizontalLayout"));
nameLabel = new QLabel(gridLayoutWidget_2);
nameLabel->setObjectName(QStringLiteral("nameLabel"));
headerHorizontalLayout->addWidget(nameLabel);
nameLineEdit = new QLineEdit(gridLayoutWidget_2);
nameLineEdit->setObjectName(QStringLiteral("nameLineEdit"));
const QString& tunnelName=tunnelConfig->getName().c_str();
nameLineEdit->setText(tunnelName);
setGroupBoxTitle(tunnelName);
QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
headerHorizontalLayout->addWidget(nameLineEdit);
headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
headerHorizontalLayout->addItem(headerHorizontalSpacer);
deletePushButton = new QPushButton(gridLayoutWidget_2);
deletePushButton->setObjectName(QStringLiteral("deletePushButton"));
QObject::connect(deletePushButton, SIGNAL(released()),
this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) {
headerHorizontalLayout->addWidget(deletePushButton);
tunnelGridLayout->addLayout(headerHorizontalLayout);
//type
{
//const QString& type = tunnelConfig->getType();
QHBoxLayout * horizontalLayout_ = new QHBoxLayout();
horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_"));
typeLabel = new QLabel(gridLayoutWidget_2);
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);
tunnelGridLayout->addLayout(horizontalLayout_);
}
retranslateTunnelForm(*this);
}
void TunnelPane::deleteWidget() {
//gridLayoutWidget_2->deleteLater();
tunnelGroupBox->deleteLater();
}
void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) {
{
//number of hops of an inbound tunnel
const QString& inbound_length=i2cpParameters.getInbound_length();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
inbound_lengthLabel = new QLabel(gridLayoutWidget_2);
inbound_lengthLabel->setObjectName(QStringLiteral("inbound_lengthLabel"));
horizontalLayout_2->addWidget(inbound_lengthLabel);
inbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2);
inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit"));
inbound_lengthLineEdit->setText(inbound_length);
inbound_lengthLineEdit->setMaximumWidth(80);
QObject::connect(inbound_lengthLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(inbound_lengthLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//number of hops of an outbound tunnel
const QString& outbound_length=i2cpParameters.getOutbound_length();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
outbound_lengthLabel = new QLabel(gridLayoutWidget_2);
outbound_lengthLabel->setObjectName(QStringLiteral("outbound_lengthLabel"));
horizontalLayout_2->addWidget(outbound_lengthLabel);
outbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2);
outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit"));
outbound_lengthLineEdit->setText(outbound_length);
outbound_lengthLineEdit->setMaximumWidth(80);
QObject::connect(outbound_lengthLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(outbound_lengthLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//number of inbound tunnels
const QString& inbound_quantity=i2cpParameters.getInbound_quantity();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
inbound_quantityLabel = new QLabel(gridLayoutWidget_2);
inbound_quantityLabel->setObjectName(QStringLiteral("inbound_quantityLabel"));
horizontalLayout_2->addWidget(inbound_quantityLabel);
inbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2);
inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit"));
inbound_quantityLineEdit->setText(inbound_quantity);
inbound_quantityLineEdit->setMaximumWidth(80);
QObject::connect(inbound_quantityLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(inbound_quantityLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//number of outbound tunnels
const QString& outbound_quantity=i2cpParameters.getOutbound_quantity();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
outbound_quantityLabel = new QLabel(gridLayoutWidget_2);
outbound_quantityLabel->setObjectName(QStringLiteral("outbound_quantityLabel"));
horizontalLayout_2->addWidget(outbound_quantityLabel);
outbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2);
outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit"));
outbound_quantityLineEdit->setText(outbound_quantity);
outbound_quantityLineEdit->setMaximumWidth(80);
QObject::connect(outbound_quantityLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(outbound_quantityLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//number of ElGamal/AES tags to send
const QString& crypto_tagsToSend=i2cpParameters.getCrypto_tagsToSend();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
crypto_tagsToSendLabel = new QLabel(gridLayoutWidget_2);
crypto_tagsToSendLabel->setObjectName(QStringLiteral("crypto_tagsToSendLabel"));
horizontalLayout_2->addWidget(crypto_tagsToSendLabel);
crypto_tagsToSendLineEdit = new QLineEdit(gridLayoutWidget_2);
crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit"));
crypto_tagsToSendLineEdit->setText(crypto_tagsToSend);
crypto_tagsToSendLineEdit->setMaximumWidth(80);
QObject::connect(crypto_tagsToSendLineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset
const QString& value=i2cpParameters.getExplicitPeers();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
explicitPeersLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
explicitPeersLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
const QString& value=i2cpParameters.get_i2p_streaming_initialAckDelay();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2p_streaming_initialAckDelayLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2p_streaming_initialAckDelayLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2p.streaming.answerPings -- enable sending pongs. true by default
const bool value=i2cpParameters.get_i2p_streaming_answerPings();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QCheckBox *_CheckBox;
i2p_streaming_answerPingsCheckBox = _CheckBox = new QCheckBox(gridLayoutWidget_2);
_CheckBox->setObjectName(QStringLiteral("_CheckBox"));
horizontalLayout_2->addWidget(_CheckBox);
_CheckBox->setChecked(value);
QObject::connect(_CheckBox, SIGNAL(toggled(bool)),
this, SLOT(updated()));
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
const QString& value=i2cpParameters.get_i2cp_leaseSetType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
const QString& value=i2cpParameters.get_i2cp_leaseSetEncType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetEncTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetEncTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
const QString& value=i2cpParameters.get_i2cp_leaseSetPrivKey();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetPrivKeyLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetPrivKeyLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
{
//i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
const QString& value=i2cpParameters.get_i2cp_leaseSetAuthType();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
QLabel *_Label;
i2cp_leaseSetAuthTypeLabel = _Label = new QLabel(gridLayoutWidget_2);
_Label->setObjectName(QStringLiteral("_Label"));
horizontalLayout_2->addWidget(_Label);
QLineEdit *_LineEdit;
i2cp_leaseSetAuthTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2);
_LineEdit->setObjectName(QStringLiteral("_LineEdit"));
_LineEdit->setText(value);
_LineEdit->setMaximumWidth(80);
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(updated()));
horizontalLayout_2->addWidget(_LineEdit);
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
retranslateI2CPParameters();
}
void TunnelPane::updated() {
std::string oldName=tunnelConfig->getName();
//validate and show red if invalid
hideWrongInputLabel();
if(!mainWindow->applyTunnelsUiToConfigs())return;
tunnelsPageUpdateListener->updated(oldName, tunnelConfig);
}
void TunnelPane::deleteButtonReleased() {
QMessageBox msgBox;
msgBox.setText(QApplication::tr("Are you sure to delete this tunnel?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Ok:
// OK was clicked
hideWrongInputLabel();
tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName());
break;
case QMessageBox::Cancel:
// Cancel was clicked
return;
}
}
/*
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
*/
QString TunnelPane::readTunnelTypeComboboxData() {
return tunnelTypeComboBox->currentData().toString();
}
i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) {
return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt();
}
void TunnelPane::deleteTunnelForm() {
widgetlocks.deleteListeners();
}
void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) {
wrongInputPane->setVisible(true);
wrongInputLabel->setText(warningText);
mainWindow->adjustSizesAccordingToWrongLabel();
if(controlWithWrongInput){
mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput);
controlWithWrongInput->setFocus();
}
mainWindow->showTunnelsPage();
}
void TunnelPane::hideWrongInputLabel() const {
wrongInputPane->setVisible(false);
mainWindow->adjustSizesAccordingToWrongLabel();
}
bool TunnelPane::isValidSingleLine(QLineEdit* widget) {
return ::isValidSingleLine(widget, WrongInputPageEnum::tunnelsSettingsPage, mainWindow);
}

191
qt/i2pd_qt/TunnelPane.h

@ -1,191 +0,0 @@ @@ -1,191 +0,0 @@
#ifndef TUNNELPANE_H
#define TUNNELPANE_H
#include "QObject"
#include "QWidget"
#include "QComboBox"
#include "QGridLayout"
#include "QLabel"
#include "QPushButton"
#include "QApplication"
#include "QLineEdit"
#include "QGroupBox"
#include "QVBoxLayout"
#include "QCheckBox"
#include "TunnelConfig.h"
#include <widgetlock.h>
#include <widgetlockregistry.h>
class ServerTunnelPane;
class ClientTunnelPane;
class TunnelConfig;
class I2CPParameters;
class MainWindow;
class TunnelPane : public QObject {
Q_OBJECT
public:
TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_);
virtual ~TunnelPane(){}
void deleteTunnelForm();
void hideWrongInputLabel() const;
void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput);
virtual ServerTunnelPane* asServerTunnelPane()=0;
virtual ClientTunnelPane* asClientTunnelPane()=0;
void deleteWidget();
protected:
MainWindow* mainWindow;
QWidget * wrongInputPane;
QLabel* wrongInputLabel;
TunnelConfig* tunnelConfig;
widgetlockregistry widgetlocks;
TunnelsPageUpdateListener* tunnelsPageUpdateListener;
QVBoxLayout *tunnelGridLayout;
QGroupBox *tunnelGroupBox;
QWidget* gridLayoutWidget_2;
//header
QLabel *nameLabel;
QLineEdit *nameLineEdit;
public:
QLineEdit * getNameLineEdit() { return nameLineEdit; }
public slots:
void updated();
void deleteButtonReleased();
protected:
QSpacerItem *headerHorizontalSpacer;
QPushButton *deletePushButton;
//type
QComboBox *tunnelTypeComboBox;
QLabel *typeLabel;
//i2cp
QLabel * inbound_lengthLabel;
QLineEdit * inbound_lengthLineEdit;
QLabel * outbound_lengthLabel;
QLineEdit * outbound_lengthLineEdit;
QLabel * inbound_quantityLabel;
QLineEdit * inbound_quantityLineEdit;
QLabel * outbound_quantityLabel;
QLineEdit * outbound_quantityLineEdit;
QLabel * crypto_tagsToSendLabel;
QLineEdit * crypto_tagsToSendLineEdit;
QLabel * explicitPeersLabel;
QLineEdit * explicitPeersLineEdit;
QLabel * i2p_streaming_initialAckDelayLabel;
QLineEdit * i2p_streaming_initialAckDelayLineEdit;
QCheckBox * i2p_streaming_answerPingsCheckBox;
QLabel * i2cp_leaseSetTypeLabel;
QLineEdit * i2cp_leaseSetTypeLineEdit;
QLabel * i2cp_leaseSetEncTypeLabel;
QLineEdit * i2cp_leaseSetEncTypeLineEdit;
QLabel * i2cp_leaseSetPrivKeyLabel;
QLineEdit * i2cp_leaseSetPrivKeyLineEdit;
QLabel * i2cp_leaseSetAuthTypeLabel;
QLineEdit * i2cp_leaseSetAuthTypeLineEdit;
QString readTunnelTypeComboboxData();
//should be created by factory
i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox);
public:
//returns false when invalid data at UI
virtual bool applyDataFromUIToTunnelConfig() {
if(!isValidSingleLine(nameLineEdit)){
setGroupBoxTitle(QApplication::translate("tunPage", "invalid_tunnel_name"));
return false;
}
if(!isValidSingleLine(inbound_lengthLineEdit))return false;
if(!isValidSingleLine(inbound_quantityLineEdit))return false;
if(!isValidSingleLine(outbound_lengthLineEdit))return false;
if(!isValidSingleLine(outbound_quantityLineEdit))return false;
if(!isValidSingleLine(crypto_tagsToSendLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetAuthTypeLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetEncTypeLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetPrivKeyLineEdit))return false;
if(!isValidSingleLine(i2cp_leaseSetTypeLineEdit))return false;
if(!isValidSingleLine(i2p_streaming_initialAckDelayLineEdit))return false;
setGroupBoxTitle(nameLineEdit->text());
tunnelConfig->setName(nameLineEdit->text().toStdString());
tunnelConfig->setType(readTunnelTypeComboboxData());
I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters();
i2cpParams.setInbound_length(inbound_lengthLineEdit->text());
i2cpParams.setInbound_quantity(inbound_quantityLineEdit->text());
i2cpParams.setOutbound_length(outbound_lengthLineEdit->text());
i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text());
i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text());
i2cpParams.set_i2cp_leaseSetAuthType(i2cp_leaseSetAuthTypeLineEdit->text());
i2cpParams.set_i2cp_leaseSetEncType(i2cp_leaseSetEncTypeLineEdit->text());
i2cpParams.set_i2cp_leaseSetPrivKey(i2cp_leaseSetPrivKeyLineEdit->text());
i2cpParams.set_i2cp_leaseSetType(i2cp_leaseSetTypeLineEdit->text());
i2cpParams.set_i2p_streaming_answerPings(i2p_streaming_answerPingsCheckBox->isChecked());
i2cpParams.set_i2p_streaming_initialAckDelay(i2p_streaming_initialAckDelayLineEdit->text());
return true;
}
protected:
void setupTunnelPane(
TunnelConfig* tunnelConfig,
QGroupBox *tunnelGroupBox,
QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox,
QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h);
void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex);
public:
int height() {
return gridLayoutWidget_2?gridLayoutWidget_2->height():0;
}
protected slots:
virtual void setGroupBoxTitle(const QString & title)=0;
private:
void retranslateTunnelForm(TunnelPane& ui) {
ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0));
ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0));
}
void retranslateI2CPParameters() {
inbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an inbound tunnel:", 0));;
outbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an outbound tunnel:", 0));;
inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));;
outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));;
crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));;
explicitPeersLabel->setText(QApplication::translate("tunForm", "List of comma-separated b64 addresses of peers to use:", 0));;
i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0));
i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0));
i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0));
i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separ. encr. types to be used in LeaseSet type 3 or 5:", 0));
i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0));
i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0));
}
protected:
bool isValidSingleLine(QLineEdit* widget);
};
#endif // TUNNELPANE_H

12
qt/i2pd_qt/TunnelsPageUpdateListener.h

@ -1,12 +0,0 @@ @@ -1,12 +0,0 @@
#ifndef TUNNELSPAGEUPDATELISTENER_H
#define TUNNELSPAGEUPDATELISTENER_H
class TunnelConfig;
class TunnelsPageUpdateListener {
public:
virtual void updated(std::string oldName, TunnelConfig* tunConf)=0;
virtual void needsDeleting(std::string oldName)=0;
};
#endif // TUNNELSPAGEUPDATELISTENER_H

2
qt/i2pd_qt/data/.gitignore vendored

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
*.tmp.xml

BIN
qt/i2pd_qt/data/icons/128x128/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

BIN
qt/i2pd_qt/data/icons/16x16/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
qt/i2pd_qt/data/icons/22x22/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

BIN
qt/i2pd_qt/data/icons/24x24/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

BIN
qt/i2pd_qt/data/icons/256x256/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

BIN
qt/i2pd_qt/data/icons/32x32/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

BIN
qt/i2pd_qt/data/icons/48x48/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

BIN
qt/i2pd_qt/data/icons/512x512/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

BIN
qt/i2pd_qt/data/icons/64x64/website.i2pd.i2pd.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

57
qt/i2pd_qt/data/website.i2pd.i2pd.appdata.xml

@ -1,57 +0,0 @@ @@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2018 Viktor Villainov <supervillain@riseup.net> -->
<component type="desktop">
<id>website.i2pd.i2pd</id>
<launchable type="desktop-id">website.i2pd.i2pd.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>BSD-3-Clause</project_license>
<name>i2pd</name>
<summary>Invisible Internet</summary>
<description>
<p>i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.</p>
<p>I2P (Invisible Internet Protocol) is a universal anonymous network layer.
All communications over I2P are anonymous and end-to-end encrypted, participants
don't reveal their real IP addresses. </p>
<p>I2P allows people from all around the world to communicate and share information
without restrictions.</p>
<p>Features:</p>
<ul>
<li>Distributed anonymous networking framework</li>
<li>End-to-end encrypted communications</li>
<li>Small footprint, simple dependencies, fast performance</li>
<li>Rich set of APIs for developers of secure applications</li>
</ul>
</description>
<screenshots>
<screenshot type="default">
<image height="590" width="923">https://i2pd.website/images/i2pd_qt.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://i2pd.website/</url>
<url type="bugtracker">https://github.com/PurpleI2P/i2pd/issues</url>
<url type="help">https://i2pd.readthedocs.io/en/latest/</url>
<update_contact>supervillain@riseup.net</update_contact>
<developer_name>PurpleI2P Team</developer_name>
<translation type="qt" />
<releases>
<release version="2.35.0" date="2020-11-30" />
<release version="2.34.0" date="2020-10-27" />
<release version="2.33.0" date="2020-08-24" />
<release version="2.32.1" date="2020-06-02" />
<release version="2.32.0" date="2020-05-25" />
<release version="2.31.0" date="2020-04-10" />
<release version="2.30.0" date="2020-02-25" />
<release version="2.29.0" date="2019-10-21" />
<release version="2.28.0" date="2019-08-27" />
<release version="2.27.0" date="2019-07-03" />
<release version="2.26.0" date="2019-06-07" />
<release version="2.25.0" date="2019-05-09" />
<release version="2.24.0" date="2019-03-21" />
<release version="2.23.0" date="2019-01-21" />
<release version="2.22.0" date="2018-11-09" />
<release version="2.21.1" date="2018-10-22" />
<release version="2.21.0" date="2018-10-04" />
</releases>
<content_rating type="oars-1.1" />
</component>

11
qt/i2pd_qt/data/website.i2pd.i2pd.desktop

@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
[Desktop Entry]
Categories=Network;P2P;Qt;
Exec=i2pd_qt
GenericName=Invisible Internet
Comment=A universal anonymous network layer
Icon=website.i2pd.i2pd
Name=i2pd
Terminal=false
Type=Application
StartupNotify=false
Keywords=i2p;i2pd;vpn;p2p;

3810
qt/i2pd_qt/generalsettingswidget.ui

File diff suppressed because it is too large Load Diff

6
qt/i2pd_qt/i2pd.qrc

@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/icons">
<file alias="mask">resources/icons/mask.ico</file>
<file alias="icon">resources/images/icon.png</file>
</qresource>
</RCC>

32
qt/i2pd_qt/i2pd.rc

@ -1,32 +0,0 @@ @@ -1,32 +0,0 @@
IDI_ICON1 ICON DISCARDABLE "resources/icons/mask.ico"
#include <windows.h> // needed for VERSIONINFO
#include "../../libi2pd/version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4" // U.S. English - multilingual (hex)
BEGIN
VALUE "CompanyName", "PurpleI2P"
VALUE "FileDescription", "I2Pd Qt"
VALUE "FileVersion", I2PD_VERSION
VALUE "InternalName", "i2pd-qt"
VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project"
VALUE "LegalTrademarks1", "Distributed under the BSD 3-Clause software license, see the accompanying file COPYING or https://opensource.org/licenses/BSD-3-Clause."
VALUE "OriginalFilename", "i2pd_qt.exe"
VALUE "ProductName", "i2pd-qt"
VALUE "ProductVersion", I2P_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
END
END

179
qt/i2pd_qt/i2pd_qt.pro

@ -1,179 +0,0 @@ @@ -1,179 +0,0 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = i2pd_qt
TEMPLATE = app
QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-deprecated-copy
CONFIG += strict_c++ c++11
CONFIG(debug, debug|release) {
message(Debug build)
# do not redirect logging to std::ostream and to Log pane
DEFINES += DEBUG_WITH_DEFAULT_LOGGING
DEFINES += I2PD_QT_DEBUG
I2PDMAKE += DEBUG=yes
} else {
message(Release build)
DEFINES += I2PD_QT_RELEASE
I2PDMAKE += DEBUG=no
}
SOURCES += DaemonQT.cpp mainwindow.cpp \
ClientTunnelPane.cpp \
MainWindowItems.cpp \
ServerTunnelPane.cpp \
SignatureTypeComboboxFactory.cpp \
TunnelConfig.cpp \
TunnelPane.cpp \
textbrowsertweaked1.cpp \
pagewithbackbutton.cpp \
widgetlock.cpp \
widgetlockregistry.cpp \
logviewermanager.cpp \
DelayedSaveManager.cpp \
Saver.cpp \
DelayedSaveManagerImpl.cpp \
SaverImpl.cpp \
../../daemon/Daemon.cpp \
../../daemon/HTTPServer.cpp \
../../daemon/I2PControl.cpp \
../../daemon/i2pd.cpp \
../../daemon/UPnP.cpp \
AboutDialog.cpp \
I2pdQtUtil.cpp
HEADERS += DaemonQT.h mainwindow.h \
ClientTunnelPane.h \
MainWindowItems.h \
ServerTunnelPane.h \
SignatureTypeComboboxFactory.h \
TunnelConfig.h \
TunnelPane.h \
TunnelsPageUpdateListener.h \
textbrowsertweaked1.h \
pagewithbackbutton.h \
widgetlock.h \
widgetlockregistry.h \
i2pd.rc \
logviewermanager.h \
DelayedSaveManager.h \
Saver.h \
DelayedSaveManagerImpl.h \
SaverImpl.h \
../../daemon/Daemon.h \
../../daemon/HTTPServer.h \
../../daemon/I2PControl.h \
../../daemon/UPnP.h \
AboutDialog.h \
BuildDateTimeQt.h \
I2pdQtUtil.h \
I2pdQtTypes.h
INCLUDEPATH += ../../libi2pd
INCLUDEPATH += ../../libi2pd_client
INCLUDEPATH += ../../daemon
INCLUDEPATH += .
FORMS += mainwindow.ui \
tunnelform.ui \
statusbuttons.ui \
routercommandswidget.ui \
generalsettingswidget.ui \
AboutDialog.ui
LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz
libi2pd.commands = @echo Building i2pd libraries
libi2pd.target = $$PWD/../../libi2pd.a
libi2pd.depends = i2pd FORCE
i2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE mk_obj_dir api_client
i2pd.target += $$PWD/../../libi2pdclient.a
i2pd.depends = FORCE
cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean
cleani2pd.depends = clean
BuildDateTimeQtTarget.target = BuildDateTimeQt.h
BuildDateTimeQtTarget.depends = FORCE
# 'touch' is unix-only; will probably break on non-unix, TBD
BuildDateTimeQtTarget.commands = touch $$PWD/BuildDateTimeQt.h
PRE_TARGETDEPS += BuildDateTimeQt.h
QMAKE_EXTRA_TARGETS += BuildDateTimeQtTarget
# git only, port to other VCS, too. TBD
DEFINES += VCS_COMMIT_INFO="\\\"git:$(shell git -C \""$$_PRO_FILE_PWD_"\" describe)\\\""
PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a
QMAKE_EXTRA_TARGETS += cleani2pd i2pd libi2pd
CLEAN_DEPS += cleani2pd
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
LIBS += -Wl,-dead_strip
LIBS += -Wl,-dead_strip_dylibs
LIBS += -Wl,-bind_at_load
}
linux:!android {
message("Using Linux settings")
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
}
windows {
message("Using Windows settings")
RC_FILE = i2pd.rc
DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB
DEFINES -= UNICODE _UNICODE
BOOST_SUFFIX = -mt
QMAKE_CXXFLAGS_RELEASE = -Os
QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows
# linker's -s means "strip"
QMAKE_LFLAGS_RELEASE += -s
LIBS = \
$$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a \
-lminiupnpc \
-lboost_system$$BOOST_SUFFIX \
-lboost_date_time$$BOOST_SUFFIX \
-lboost_filesystem$$BOOST_SUFFIX \
-lboost_program_options$$BOOST_SUFFIX \
-lssl \
-lcrypto \
-lz \
-lwsock32 \
-lws2_32 \
-lgdi32 \
-liphlpapi \
-lstdc++ \
-lpthread
}
!android:!symbian:!maemo5:!simulator {
message("Build with a system tray icon")
# see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince*
#sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images
RESOURCES = i2pd.qrc
QT += xml
#INSTALLS += sources
}

45
qt/i2pd_qt/logviewermanager.cpp

@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
#include "logviewermanager.h"
LogViewerManager::LogViewerManager(std::shared_ptr<std::iostream> logStream_,
QPlainTextEdit* logTextEdit_,
QObject *parent) :
QObject(parent),
logStream(logStream_),
logTextEdit(logTextEdit_),
controllerForBgThread(nullptr)
{
assert(logTextEdit!=nullptr);
controllerForBgThread=new i2pd::qt::logviewer::Controller(*this);
}
namespace i2pd {
namespace qt {
namespace logviewer {
QString Worker::pollAndShootATimerForInfiniteRetries() {
std::shared_ptr<std::iostream> logStream=logViewerManager.getLogStream();
if(!logStream)return "";
std::streamsize MAX_SZ=64*1024;
char*buf=(char*)malloc(MAX_SZ*sizeof(char));
if(buf==nullptr)return "";
std::streamsize read=logStream->readsome(buf, MAX_SZ);
if(read<0)read=0;
QString ret=QString::fromUtf8(buf, read);
free(buf);
return ret;
}
Controller::Controller(LogViewerManager &parameter1):logViewerManager(parameter1) {
Worker *worker = new Worker(parameter1);
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate1, worker, &Worker::doWork1);
connect(worker, &Worker::resultReady,
&parameter1, &LogViewerManager::appendPlainText_atGuiThread);
workerThread.start();
timerId=startTimer(100/*millis*/);
}
}
}
}

130
qt/i2pd_qt/logviewermanager.h

@ -1,130 +0,0 @@ @@ -1,130 +0,0 @@
#ifndef LOGVIEWERMANAGER_H
#define LOGVIEWERMANAGER_H
#include <QObject>
#include <QString>
#include <QPlainTextEdit>
#include <QScrollBar>
#include <QComboBox>
#include <QTimer>
#include <QThread>
#include <assert.h>
#include <string>
#include "FS.h"
#include "Log.h"
class LogViewerManager;
namespace i2pd {
namespace qt {
namespace logviewer {
class Worker : public QObject
{
Q_OBJECT
private:
LogViewerManager &logViewerManager;
public:
Worker(LogViewerManager &parameter1):logViewerManager(parameter1){}
private:
QString pollAndShootATimerForInfiniteRetries();
public slots:
void doWork1() {
/* ... here is the expensive or blocking operation ... */
QString read=pollAndShootATimerForInfiniteRetries();
emit resultReady(read);
}
signals:
void resultReady(QString read);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
LogViewerManager& logViewerManager;
int timerId;
public:
Controller(LogViewerManager &parameter1);
~Controller() {
if(timerId!=0)killTimer(timerId);
workerThread.quit();
workerThread.wait();
}
signals:
void operate1();
protected:
void timerEvent(QTimerEvent */*event*/) {
emit operate1();
}
};
}
}
}
class LogViewerManager : public QObject
{
Q_OBJECT
private:
std::shared_ptr<std::iostream> logStream;
QPlainTextEdit* logTextEdit;
i2pd::qt::logviewer::Controller* controllerForBgThread;
public:
//also starts a bg thread (QTimer) polling logStream->readsome(buf, n)
explicit LogViewerManager(std::shared_ptr<std::iostream> logStream_,
QPlainTextEdit* logTextEdit_,
QObject *parent);
//also deallocs the bg thread (QTimer)
virtual ~LogViewerManager(){}
const i2pd::qt::logviewer::Controller& getControllerForBgThread() {
assert(controllerForBgThread!=nullptr);
return *controllerForBgThread;
}
const QPlainTextEdit* getLogTextEdit(){ return logTextEdit; }
const std::shared_ptr<std::iostream> getLogStream(){ return logStream; }
signals:
public slots:
//void appendFromNonGuiThread(std::string read) {
//}
public slots:
void appendPlainText_atGuiThread(QString plainText) {
if(plainText.length()==0)return;
assert(logTextEdit!=nullptr);
int scrollPosVert =logTextEdit->verticalScrollBar()->value();
int scrollPosHoriz=logTextEdit->horizontalScrollBar()->value();
int scrollPosVertMax =logTextEdit->verticalScrollBar()->maximum();
const int MAX_LINES=10*1024;
logTextEdit->setMaximumBlockCount(MAX_LINES);
//logTextEdit->appendPlainText(plainText);
//navigate the window to the end
//QTextCursor cursor = logTextEdit->textCursor();
//cursor.movePosition(QTextCursor::MoveOperation::End);
//logTextEdit->setTextCursor(cursor);
//QTextCursor prev_cursor = logTextEdit->textCursor();
logTextEdit->moveCursor(QTextCursor::End);
logTextEdit->insertPlainText(plainText);
if(/*prev_cursor.atEnd()*/scrollPosVert==scrollPosVertMax){
//logTextEdit->moveCursor(QTextCursor::End);
scrollPosVert =logTextEdit->verticalScrollBar()->maximum();
scrollPosHoriz=logTextEdit->horizontalScrollBar()->minimum();
}
//else
// logTextEdit->setTextCursor(prev_cursor);
logTextEdit->verticalScrollBar()->setValue(scrollPosVert);
logTextEdit->horizontalScrollBar()->setValue(scrollPosHoriz);
}
/*
void replaceText_atGuiThread() {
assert(logTextEdit!=nullptr);
logTextEdit->setText(QString::fromStdString(nav.getContent()));
}
*/
};
#endif // LOGVIEWERMANAGER_H

1126
qt/i2pd_qt/mainwindow.cpp

File diff suppressed because it is too large Load Diff

883
qt/i2pd_qt/mainwindow.h

@ -1,883 +0,0 @@ @@ -1,883 +0,0 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QObject>
#include <QMainWindow>
#include <QPushButton>
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QAction>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpacerItem>
#include "QVBoxLayout"
#include "QUrl"
#ifndef ANDROID
# include <QSystemTrayIcon>
# include <QCloseEvent>
# include <QMenu>
#endif
#include <QString>
#include <functional>
#include "MainWindowItems.h"
#include "TunnelPane.h"
#include "ServerTunnelPane.h"
#include "ClientTunnelPane.h"
#include "TunnelConfig.h"
#include "textbrowsertweaked1.h"
#include "Config.h"
#include "FS.h"
#include <QDebug>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include "TunnelsPageUpdateListener.h"
#include "DaemonQT.h"
#include "SignatureTypeComboboxFactory.h"
#include "pagewithbackbutton.h"
#include <iostream>
#include "widgetlockregistry.h"
#include "widgetlock.h"
#include "DelayedSaveManager.h"
#include "DelayedSaveManagerImpl.h"
#include "SaverImpl.h"
#include "I2pdQtUtil.h"
class SaverImpl;
class LogViewerManager;
template<typename ValueType>
bool isType(boost::any& a) {
return
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
std::strcmp(a.type().name(), typeid(ValueType).name()) == 0
#else
a.type() == typeid(ValueType)
#endif
;
}
class ConfigOption {
public:
QString section;
QString option;
//MainWindow::DefaultValueGetter defaultValueGetter;
ConfigOption(QString section_, QString option_/*, DefaultValueGetter defaultValueGetter_*/):
section(section_)
, option(option_)
//, defaultValueGetter(defaultValueGetter_)
{}
};
extern std::string programOptionsWriterCurrentSection;
class MainWindow;
class MainWindowItem : public QObject {
Q_OBJECT
private:
ConfigOption option;
QWidget* widgetToFocus;
QString requirementToBeValid;
const bool readOnly;
public:
MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_, bool readOnly_=false) :
option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), readOnly(readOnly_) {}
QWidget* getWidgetToFocus(){return widgetToFocus;}
QString& getRequirementToBeValid() { return requirementToBeValid; }
ConfigOption& getConfigOption() { return option; }
boost::any optionValue;
virtual ~MainWindowItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){
std::string optName="";
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
optName+=option.option.toStdString();
//qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
boost::any programOption;
i2p::config::GetOptionAsAny(optName, programOption);
optionValue=programOption.empty()?boost::any(std::string(""))
:boost::any_cast<boost::program_options::variable_value>(programOption).value();
}
virtual void saveToStringStream(std::stringstream& out){
if(readOnly)return; //should readOnly items (conf=) error somewhere, instead of silently skipping save?
if(isType<std::string>(optionValue)) {
std::string v = boost::any_cast<std::string>(optionValue);
if(v.empty())return;
}
if(optionValue.empty())return;
std::string rtti = optionValue.type().name();
std::string optName="";
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string(".");
optName+=option.option.toStdString();
//qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str();
std::string sectionAsStdStr = option.section.toStdString();
if(!option.section.isEmpty() &&
sectionAsStdStr!=programOptionsWriterCurrentSection) {
out << "[" << sectionAsStdStr << "]\n";
programOptionsWriterCurrentSection=sectionAsStdStr;
}
out << option.option.toStdString() << "=";
if(isType<std::string>(optionValue)) {
out << boost::any_cast<std::string>(optionValue);
}else if(isType<bool>(optionValue)) {
out << (boost::any_cast<bool>(optionValue) ? "true" : "false");
}else if(isType<uint16_t>(optionValue)) {
out << boost::any_cast<uint16_t>(optionValue);
}else if(isType<uint32_t>(optionValue)) {
out << boost::any_cast<uint32_t>(optionValue);
}else if(isType<int>(optionValue)) {
out << boost::any_cast<int>(optionValue);
}else if(isType<unsigned short>(optionValue)) {
out << boost::any_cast<unsigned short>(optionValue);
}else out << boost::any_cast<std::string>(optionValue); //let it throw
out << "\n\n";
}
virtual bool isValid(bool & alreadyDisplayedIfWrong){alreadyDisplayedIfWrong=false;return true;}
};
class NonGUIOptionItem : public MainWindowItem {
public:
NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {}
virtual ~NonGUIOptionItem(){}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class BaseStringItem : public MainWindowItem {
Q_OBJECT
public:
QLineEdit* lineEdit;
MainWindow *mainWindow;
BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_, MainWindow* mainWindow_, bool readOnly=false):
MainWindowItem(option_, lineEdit_, requirementToBeValid_, readOnly),
lineEdit(lineEdit_),
mainWindow(mainWindow_)
{};
virtual ~BaseStringItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual QString toString(){
return boost::any_cast<std::string>(optionValue).c_str();
}
virtual boost::any fromString(QString s){return boost::any(s.toStdString());}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
lineEdit->setText(toString());
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=fromString(lineEdit->text());
MainWindowItem::saveToStringStream(out);
}
virtual bool isValid(bool & alreadyDisplayedIfWrong);
};
class FileOrFolderChooserItem : public BaseStringItem {
protected:
const bool requireExistingFile;
public:
QPushButton* browsePushButton;
FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile_, bool readOnly) :
BaseStringItem(option_, lineEdit_, QString(), mw, readOnly), requireExistingFile(requireExistingFile_), browsePushButton(browsePushButton_) {}
virtual ~FileOrFolderChooserItem(){}
};
class FileChooserItem : public FileOrFolderChooserItem {
Q_OBJECT
private slots:
void pushButtonReleased();
public:
FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile, bool readOnly) :
FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFile, readOnly) {
QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
}
};
class FolderChooserItem : public FileOrFolderChooserItem{
Q_OBJECT
private slots:
void pushButtonReleased();
public:
FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFolder) :
FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFolder, false) {
QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased()));
}
};
class ComboBoxItem : public MainWindowItem {
public:
QComboBox* comboBox;
ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){}
virtual ~ComboBoxItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption()=0;
virtual void saveToStringStream(std::stringstream& out)=0;
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return ; }
};
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<std::string>(optionValue).c_str();
comboBox->setCurrentText(QString(ld));
}
virtual void saveToStringStream(std::stringstream& out){
std::string logDest = comboBox->currentText().toStdString();
optionValue=logDest;
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
Q_OBJECT
};
class LogLevelComboBoxItem : public ComboBoxItem {
public:
LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}
virtual ~LogLevelComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
const char * ll = boost::any_cast<std::string>(optionValue).c_str();
comboBox->setCurrentText(QString(ll));
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=comboBox->currentText().toStdString();
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class SignatureTypeComboBoxItem : public ComboBoxItem {
public:
SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {}
virtual ~SignatureTypeComboBoxItem(){}
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
while(comboBox->count()>0)comboBox->removeItem(0);
uint16_t selected = (uint16_t) boost::any_cast<unsigned short>(optionValue);
SignatureTypeComboBoxFactory::fillComboBox(comboBox, selected);
}
virtual void saveToStringStream(std::stringstream& out){
uint16_t selected = SignatureTypeComboBoxFactory::getSigType(comboBox->currentData());
optionValue=(unsigned short)selected;
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class CheckBoxItem : public MainWindowItem {
public:
QCheckBox* checkBox;
CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){}
virtual ~CheckBoxItem(){}
virtual void installListeners(MainWindow *mainWindow);
virtual void loadFromConfigOption(){
MainWindowItem::loadFromConfigOption();
//qDebug() << "setting value for checkbox " << checkBox->text();
checkBox->setChecked(boost::any_cast<bool>(optionValue));
}
virtual void saveToStringStream(std::stringstream& out){
optionValue=checkBox->isChecked();
MainWindowItem::saveToStringStream(out);
}
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
};
class BaseFormattedStringItem : public BaseStringItem {
public:
QString fieldNameTranslated;
BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_, MainWindow* mw) :
BaseStringItem(option_, lineEdit_, requirementToBeValid_, mw), fieldNameTranslated(fieldNameTranslated_) {}
virtual ~BaseFormattedStringItem(){}
//virtual bool isValid(bool & alreadyDisplayedIfWrong)=0;
};
class IntegerStringItem : public BaseFormattedStringItem {
public:
IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer."), mw) {}
virtual ~IntegerStringItem(){}
virtual bool isValid(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toInt(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<int>(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_, MainWindow* mw) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer."), mw) {}
virtual ~UShortStringItem(){}
virtual bool isValid(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<unsigned short>(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_, MainWindow* mw) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer."), mw) {}
virtual ~UInt32StringItem(){}
virtual bool isValid(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUInt(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<uint32_t>(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_, MainWindow* mw) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer."), mw) {}
virtual ~UInt16StringItem(){}
virtual bool isValid(bool & alreadyDisplayedIfWrong){
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong);
if(!correct)return false;
alreadyDisplayedIfWrong = false;
auto str=lineEdit->text();
bool ok;
str.toUShort(&ok);
return ok;
}
virtual QString toString(){return QString::number(boost::any_cast<uint16_t>(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_, MainWindow* mw) :
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address"), mw) {}
//virtual bool isValid(bool & alreadyDisplayedIfWrong){return true;}//todo
};
class TCPPortStringItem : public UShortStringItem {
public:
TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) :
UShortStringItem(option_, lineEdit_, fieldNameTranslated_,mw) {}
};
namespace Ui {
class MainWindow;
class StatusButtonsForm;
class routerCommandsWidget;
class GeneralSettingsContentsForm;
}
using namespace i2p::client;
class TunnelPane;
using namespace i2p::qt;
class Controller;
class DelayedSaveManagerImpl;
class MainWindow : public QMainWindow {
Q_OBJECT
private:
std::string currentLocalDestinationB32;
std::shared_ptr<std::iostream> logStream;
DelayedSaveManagerImpl* delayedSaveManagerPtr;
DelayedSaveManager::DATA_SERIAL_TYPE dataSerial;
public:
explicit MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *parent=nullptr);
~MainWindow();
void setI2PController(i2p::qt::Controller* controller_);
void highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus);
//typedef std::function<QString ()> DefaultValueGetter;
//#ifndef ANDROID
// 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 updated();
void handleQuitButton();
void handleGracefulQuitButton();
void handleDoRestartButton();
void handleGracefulQuitTimerEvent();
#ifndef ANDROID
void setIcon();
void iconActivated(QSystemTrayIcon::ActivationReason reason);
void toggleVisibilitySlot();
#endif
void scheduleStatusPageUpdates();
void statusHtmlPageMouseReleased();
void statusHtmlPageSelectionChanged();
void updateStatusPage();
void showStatusMainPage();
void showStatus_commands_Page();
void runPeerTest();
void enableTransit();
void disableTransit();
public slots:
void syncLogLevel (int comboBoxIndex);
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 showLogViewerPage();
void showSettingsPage();
void showTunnelsPage();
void showRestartPage();
void showQuitPage();
void showAboutBox(const QString & href);
private:
StatusPage statusPage;
QTimer * statusPageUpdateTimer;
bool wasSelectingAtStatusMainPage;
bool showHiddenInfoStatusMainPage;
LogViewerManager *logViewerManagerPtr;
void showStatusPage(StatusPage newStatusPage);
#ifndef ANDROID
void createActions();
void createTrayIcon();
bool quitting;
QAction *toggleWindowVisibleAction;
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
#endif
public:
Ui::MainWindow* ui;
Ui::StatusButtonsForm* statusButtonsUI;
Ui::routerCommandsWidget* routerCommandsUI;
Ui::GeneralSettingsContentsForm* uiSettings;
void adjustSizesAccordingToWrongLabel();
bool applyTunnelsUiToConfigs();
private:
int settingsTitleLabelNominalHeight;
TextBrowserTweaked1 * textBrowser;
QWidget * routerCommandsParent;
PageWithBackButton * pageWithBackButton;
TextBrowserTweaked1 * childTextBrowser;
widgetlockregistry widgetlocks;
i2p::qt::Controller* i2pController;
protected:
void updateRouterCommandsButtons();
#ifndef ANDROID
void closeEvent(QCloseEvent *event);
#endif
void resizeEvent(QResizeEvent* event);
void onResize();
void setStatusButtonsVisible(bool visible);
QString getStatusPageHtml(bool showHiddenInfo);
QList<MainWindowItem*> configItems;
NonGUIOptionItem* daemonOption;
NonGUIOptionItem* serviceOption;
//LogDestinationComboBoxItem* logOption;
FileChooserItem* logFileNameOption;
FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile, bool readOnly=false);
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);
void initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated);
void initCheckBox(ConfigOption option, QCheckBox* checkBox);
void initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
void initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
void initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated);
void initStringBox(ConfigOption option, QLineEdit* lineEdit);
NonGUIOptionItem* initNonGUIOption(ConfigOption option);
void loadAllConfigs(SaverImpl* saverPtr);
void layoutTunnels();
public slots:
/** returns false iff not valid items present and save was aborted */
bool saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::string tunnelNameToFocus="", QWidget* widgetToFocus=nullptr);
void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus, QWidget* widgetToFocus);
void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI("", nullptr); }
//focus none
void reloadTunnelsConfigAndUI_QString(QString tunnelNameToFocus);
void addServerTunnelPushButtonReleased();
void addClientTunnelPushButtonReleased();
void anchorClickedHandler(const QUrl & link);
void backClickedFromChild();
void logDestinationComboBoxValueChanged(const QString & text);
private:
QString datadir;
QString confpath;
QString tunconfpath;
std::map<std::string, TunnelConfig*> tunnelConfigs;
std::list<TunnelPane*> tunnelPanes;
void appendTunnelForms(std::string tunnelNameToFocus);
void deleteTunnelForms();
void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf);
template<typename Section>
std::string GetI2CPOption (const Section& section, const std::string& name, const std::string& value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value);
}
template<typename Section>
std::string GetI2CPOption (const Section& section, const std::string& name, const char* value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::string (value));
}
template<typename Section, typename Type>
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
{
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
}
template<typename Section>
void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options, I2CPParameters& param
/*TODO fill param*/) const
{
std::string _INBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
param.setInbound_length(QString(_INBOUND_TUNNEL_LENGTH.c_str()));
std::string _OUTBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
param.setOutbound_length(QString(_OUTBOUND_TUNNEL_LENGTH.c_str()));
std::string _INBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
param.setInbound_quantity( QString(_INBOUND_TUNNELS_QUANTITY.c_str()));
std::string _OUTBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str()));
std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str()));
std::string _i2cp_leaseSetAuthType = options[I2CP_PARAM_LEASESET_AUTH_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0);
param.set_i2cp_leaseSetAuthType(QString(_i2cp_leaseSetAuthType.c_str()));
const char DEFAULT_LEASESET_ENCRYPTION_TYPE[] = "";
std::string _i2cp_leaseSetEncType = options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, DEFAULT_LEASESET_ENCRYPTION_TYPE);//todo Identity's type by default
param.set_i2cp_leaseSetEncType(QString(_i2cp_leaseSetEncType.c_str()));
std::string _i2cp_leaseSetPrivKey = options[I2CP_PARAM_LEASESET_PRIV_KEY] = GetI2CPOption (section, I2CP_PARAM_LEASESET_PRIV_KEY, "");
param.set_i2cp_leaseSetPrivKey(QString(_i2cp_leaseSetPrivKey.c_str()));
std::string _i2cp_leaseSetType = options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE);
param.set_i2cp_leaseSetType(QString(_i2cp_leaseSetType.c_str()));
std::string _i2p_streaming_answerPings= options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption (section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS);
param.set_i2p_streaming_answerPings((_i2p_streaming_answerPings.compare("true")==0)||(_i2p_streaming_answerPings.compare("yes")==0));
std::string _i2p_streaming_initialAckDelay = options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption (section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY);
param.set_i2p_streaming_initialAckDelay(QString(_i2p_streaming_initialAckDelay.c_str()));
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param
}
void CreateDefaultI2CPOptions (I2CPParameters& param
/*TODO fill param*/) const
{
const int _INBOUND_TUNNEL_LENGTH = DEFAULT_INBOUND_TUNNEL_LENGTH;
param.setInbound_length(QString::number(_INBOUND_TUNNEL_LENGTH));
const int _OUTBOUND_TUNNEL_LENGTH = DEFAULT_OUTBOUND_TUNNEL_LENGTH;
param.setOutbound_length(QString::number(_OUTBOUND_TUNNEL_LENGTH));
const int _INBOUND_TUNNELS_QUANTITY = DEFAULT_INBOUND_TUNNELS_QUANTITY;
param.setInbound_quantity( QString::number(_INBOUND_TUNNELS_QUANTITY));
const int _OUTBOUND_TUNNELS_QUANTITY = DEFAULT_OUTBOUND_TUNNELS_QUANTITY;
param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY));
const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND;
param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND));
const int _i2cp_leaseSetAuthType = 0;
param.set_i2cp_leaseSetAuthType(QString::number(_i2cp_leaseSetAuthType));
const QString _i2cp_leaseSetEncType = "0,4"; //todo Identity's type by default
param.set_i2cp_leaseSetEncType(_i2cp_leaseSetEncType);
param.set_i2cp_leaseSetPrivKey("");
const int _i2cp_leaseSetType = DEFAULT_LEASESET_TYPE;
param.set_i2cp_leaseSetType(QString::number(_i2cp_leaseSetType));
bool _i2p_streaming_answerPings= DEFAULT_ANSWER_PINGS;
param.set_i2p_streaming_answerPings(_i2p_streaming_answerPings);
const int _i2p_streaming_initialAckDelay = DEFAULT_INITIAL_ACK_DELAY;
param.set_i2p_streaming_initialAckDelay(QString::number(_i2p_streaming_initialAckDelay));
}
void DeleteTunnelNamed(std::string name) {
std::map<std::string,TunnelConfig*>::const_iterator it=tunnelConfigs.find(name);
if(it!=tunnelConfigs.end()){
TunnelConfig* tc=it->second;
deleteTunnelFromUI(name, tc);
tunnelConfigs.erase(it);
delete tc;
}
saveAllConfigs(true, FocusEnum::noFocus);
}
std::string GenerateNewTunnelName() {
int i=1;
while(true){
std::stringstream name;
name << "name" << i;
const std::string& str=name.str();
if(tunnelConfigs.find(str)==tunnelConfigs.end())return str;
++i;
}
}
void CreateDefaultClientTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
std::string name=GenerateNewTunnelName();
std::string type = I2P_TUNNELS_SECTION_TYPE_CLIENT;
std::string dest = "127.0.0.1";
int port = 0;
std::string keys = "";
std::string address = "127.0.0.1";
int destinationPort = 0;
int cryptoType = 0;
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
// I2CP
I2CPParameters i2cpParameters;
CreateDefaultI2CPOptions (i2cpParameters);
tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
dest,
port,
keys,
address,
destinationPort,
sigType,
cryptoType);
saveAllConfigs(true, FocusEnum::focusOnTunnelName, name);
}
void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
std::string name=GenerateNewTunnelName();
std::string type=I2P_TUNNELS_SECTION_TYPE_SERVER;
std::string host = "127.0.0.1";
int port = 0;
std::string keys = "";
int inPort = 0;
std::string accessList = "";
std::string hostOverride = "";
std::string webircpass = "";
bool gzip = true;
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
std::string address = "127.0.0.1";
bool isUniqueLocal = true;
int cryptoType = 0;
// I2CP
I2CPParameters i2cpParameters;
CreateDefaultI2CPOptions (i2cpParameters);
tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
host,
port,
keys,
inPort,
accessList,
hostOverride,
webircpass,
gzip,
sigType,
address,
isUniqueLocal,
cryptoType);
saveAllConfigs(true, FocusEnum::focusOnTunnelName, name);
}
void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
{
boost::property_tree::ptree pt;
std::string tunConf=tunconfpath.toStdString();
if (tunConf == "") {
// TODO: cleanup this in 2.8.0
tunConf = i2p::fs::DataDirPath ("tunnels.cfg");
if (i2p::fs::Exists(tunConf)) {
LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf);
} else {
tunConf = i2p::fs::DataDirPath ("tunnels.conf");
}
}
LogPrint(eLogDebug, "tunnels config file: ", tunConf);
try
{
boost::property_tree::read_ini (tunConf, pt);
}
catch (std::exception& ex)
{
LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ());//TODO show err box and disable tunn.page
return;
}
for (auto& section: pt)
{
std::string name = section.first;
try
{
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
{
// mandatory params
std::string dest;
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) {
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
}
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
// 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 cryptoType = section.second.get<int>(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
int destinationPort = section.second.get<int>(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
// I2CP
std::map<std::string, std::string> options;
I2CPParameters i2cpParameters;
ReadI2CPOptions (section, options, i2cpParameters);
tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters,
dest,
port,
keys,
address,
destinationPort,
sigType,
cryptoType);
}
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
{
// mandatory params
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT);
// optional params
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS, "");
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0);
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, "");
std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
int cryptoType = section.second.get<int>(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0);
// I2CP
std::map<std::string, std::string> options;
I2CPParameters i2cpParameters;
ReadI2CPOptions (section, options, i2cpParameters);
/*
std::set<i2p::data::IdentHash> idents;
if (accessList.length () > 0)
{
size_t pos = 0, comma;
do
{
comma = accessList.find (',', pos);
i2p::data::IdentHash ident;
ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
idents.insert (ident);
pos = comma + 1;
}
while (comma != std::string::npos);
}
*/
tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters,
host,
port,
keys,
inPort,
accessList,
hostOverride,
webircpass,
gzip,
sigType,
address,
isUniqueLocal,
cryptoType);
}
else
LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui
}
catch (std::exception& ex)
{
LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());//TODO show err box and disable the tunn gui
}
}
}
private:
class TunnelsPageUpdateListenerMainWindowImpl : public TunnelsPageUpdateListener {
MainWindow* mainWindow;
public:
TunnelsPageUpdateListenerMainWindowImpl(MainWindow* mainWindow_):mainWindow(mainWindow_){}
virtual void updated(std::string oldName, TunnelConfig* tunConf);
virtual void needsDeleting(std::string oldName);
};
TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener;
//void onLoggingOptionsChange() {}
SaverImpl* saverPtr;
};
#endif // MAINWINDOW_H

1053
qt/i2pd_qt/mainwindow.ui

File diff suppressed because it is too large Load Diff

24
qt/i2pd_qt/pagewithbackbutton.cpp

@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
#include "pagewithbackbutton.h"
#include "QVBoxLayout"
#include "QHBoxLayout"
#include "QPushButton"
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();
}

21
qt/i2pd_qt/pagewithbackbutton.h

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
#ifndef PAGEWITHBACKBUTTON_H
#define PAGEWITHBACKBUTTON_H
#include <QWidget>
class PageWithBackButton : public QWidget
{
Q_OBJECT
public:
explicit PageWithBackButton(QWidget *parent, QWidget* child);
signals:
void backReleased();
private slots:
void backReleasedSlot();
};
#endif // PAGEWITHBACKBUTTON_H

BIN
qt/i2pd_qt/resources/icons/mask.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

BIN
qt/i2pd_qt/resources/images/icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save