moved qt and android sources inn separate repositories
Signed-off-by: R4SAS <r4sas@i2pmail.org>
18
android/.gitignore
vendored
@ -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
|
@ -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>
|
@ -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
|
@ -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 +0,0 @@
|
||||
../../contrib/certificates
|
@ -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
|
@ -1,3 +0,0 @@
|
||||
http://inr.i2p/export/alive-hosts.txt
|
||||
http://stats.i2p/cgi-bin/newhosts.txt
|
||||
http://i2p-projekt.i2p/hosts.txt
|
@ -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 +0,0 @@
|
||||
../../contrib/tunnels.d
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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>
|
@ -1,3 +0,0 @@
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
org.gradle.parallel=true
|
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
@ -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 @@
|
||||
#!/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 @@
|
||||
@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
|
@ -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)
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
@ -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();
|
||||
}
|
@ -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
|
@ -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 *;
|
||||
#}
|
@ -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
|
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 1.9 KiB |
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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 +0,0 @@
|
||||
rootProject.name = "i2pd"
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 @@
|
||||
/build*/
|
13
qt/i2pd_qt/.gitignore
vendored
@ -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
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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><html><head/><body><p><span style=" font-weight:600;">About i2pd_qt</span></p></body></html></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>
|
@ -1,7 +0,0 @@
|
||||
#ifndef BUILDDATETIMEQT_H
|
||||
#define BUILDDATETIMEQT_H
|
||||
|
||||
#include <QString>
|
||||
const QString BUILD_DATE_TIME_QT = QStringLiteral(__DATE__ " " __TIME__);
|
||||
|
||||
#endif // BUILDDATETIMEQT_H
|
@ -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;}
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -1,3 +0,0 @@
|
||||
#include "DelayedSaveManager.h"
|
||||
|
||||
DelayedSaveManager::DelayedSaveManager(){}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -1,7 +0,0 @@
|
||||
#ifndef I2PDQTTYPES_H
|
||||
#define I2PDQTTYPES_H
|
||||
|
||||
enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage };
|
||||
enum FocusEnum { noFocus, focusOnTunnelName, focusOnWidget };
|
||||
|
||||
#endif // I2PDQTTYPES_H
|
@ -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;
|
||||
}
|
@ -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
|
@ -1,2 +0,0 @@
|
||||
#include "MainWindowItems.h"
|
||||
|
@ -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
|
@ -1,3 +0,0 @@
|
||||
# Build Requirements
|
||||
|
||||
* Qt 5 is necessary (because Qt4 lacks QtWidgets/ folder)
|
@ -1,6 +0,0 @@
|
||||
#include "Saver.h"
|
||||
|
||||
Saver::Saver()
|
||||
{
|
||||
|
||||
}
|
@ -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
|
@ -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;
|
||||
}*/
|
@ -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
|
@ -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;}
|
@ -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
|
@ -1,2 +0,0 @@
|
||||
#include "SignatureTypeComboboxFactory.h"
|
||||
|
@ -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
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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 @@
|
||||
*.tmp.xml
|
||||
|
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 7.1 KiB |
@ -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>
|
@ -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;
|
@ -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>
|
@ -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
|
@ -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
|
||||
}
|
||||
|
@ -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 ¶meter1):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,
|
||||
¶meter1, &LogViewerManager::appendPlainText_atGuiThread);
|
||||
workerThread.start();
|
||||
timerId=startTimer(100/*millis*/);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -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 ¶meter1):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 ¶meter1);
|
||||
~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
|
@ -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
|
@ -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();
|
||||
}
|
@ -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
|
Before Width: | Height: | Size: 153 KiB |
Before Width: | Height: | Size: 8.5 KiB |