Compare commits

...

336 Commits

Author SHA1 Message Date
c0a0aa7700 Failed attempt to build debian package in docker
Keep running into

    debian-binary:
         [exec] dh patch --with systemd,bash-completion
         [exec] dpkg: warning: --compare-versions used with obsolete relation operator '>'
         [exec] dh: Unknown sequence patch (choose from: binary binary-arch binary-indep build build-arch build-indep clean install install-arch install-indep)
         [exec] make: *** [debian/rules:54: patch] Error 255
2021-01-23 22:43:51 +01:00
4a9131c39d CI: Add build_docker job conditions
We shouldn't build it for every single branch and commit
2021-01-23 22:37:29 +01:00
b47269f14e CI: Fix docker load command
It wasn't working at all which mean we would never use the cache
2021-01-23 22:36:56 +01:00
fb317b44ba CI: make sure we can build Docker image 2021-01-23 22:32:10 +01:00
e64e12b3fb Fix docker build
ant needed to be updated to >1.9, but the old image used an old alpine
 with the max version of ant being 1.8.

The build is split into 2 phases to reduce the size of the image.
A builder makes the installer and installs it in one image.
The installed files are copied over to the actual result image.
2021-01-23 18:19:31 +01:00
zzz
f71e59a049 Merge branch 'test-convert' into 'master'
Test net.i2p.util.ConvertToHash

See merge request i2p-hackers/i2p.i2p!13
2021-01-20 14:38:37 +00:00
169fb59d7d test: fix I2PSocketExceptionTest::testUnknownStatus
In non-English environments, the message is translated.
2021-01-20 14:38:37 +00:00
zzz
922178b2c7 SSU: Fix deadlock with router restart
http://zzz.i2p/topics/3036
2021-01-20 09:27:55 -05:00
zzz
74a9193ba5 Console: Fix link to UPnP status 2021-01-20 09:25:58 -05:00
idk
335409f1d2 Find and fix the bug which appears in 'https://old.reddit.com/r/i2p/search?q=console&restrict_sr=on&sort=relevance&t=all' a bunch of Reddit posts, due to a mistake in the Firefox Profile Installer which expected router.config to be in the (deprecated)Roaming application data, even though it was in the Local Application Data, and if it did not exist, created it. If the (deprecated)Roaming application data directory had a router.config file, then I2P attempted to use the Roaming application directory, and the user could end up with a router that had no client apps configured, resulting in a poor UX 2021-01-18 00:26:33 -05:00
idk
d6edb9e96c Merge branch 'gitlab-ci' into 'master'
Tests on Gitlab CI

See merge request i2p-hackers/i2p.i2p!12
2021-01-17 23:10:34 +00:00
f150855f1c test: fix I2PSocketExceptionTest::testUnknownStatus
In non-English environments, the message is translated.
2021-01-17 23:10:34 +00:00
zzz
655ce09796 Console: Remove echelon.i2p from home page at op's request 2021-01-17 10:06:44 -05:00
zzz
91ebec15d5 NetDB: log/stat tweak 2021-01-17 09:51:49 -05:00
zzz
b17d321503 Ratchet: log tweaks 2021-01-17 09:47:04 -05:00
zzz
a6398d88a9 i2psnark minor cleanup 2021-01-17 09:40:11 -05:00
zzz
59969db16c Sybil: Limit stored analysis files if no console to view them
Reduce stored file time to 10 days
Min stored time is 2 * analysis interval
2021-01-17 09:32:23 -05:00
zzz
b68a5ea7fd Router: Fix up warning about no console for split config files
clean up multiple getContext() calls
2021-01-17 09:18:21 -05:00
idk
c2234685b9 eepsite=>I2P site to match the new terminology on the web site, and more fine-tuning to CSS to sharpen image appearance 2021-01-17 01:11:51 -05:00
zzz
ce7daaa02a Router: Limit max addresses in RI 2021-01-14 10:32:35 -05:00
zzz
b19999f95a Router: Move Sybil subsystem from console to router 2021-01-14 09:46:38 -05:00
zzz
92ecc9f8e8 Router: Log crashed event if old router.ping file is found at startup 2021-01-14 09:25:21 -05:00
zzz
aa2ba92db8 Router: Change default encryption type to ECIES-X25519 (proposal 156)
As of 0.9.49. 0.9.48-x dev builds will not rekey.
New installs only.
Existing install rekey probability: 1 in 128
To be increased in later releases, see proposal 156 for details.
2021-01-14 08:54:17 -05:00
zzz
5f3c41244b Jetty: Fix URI in request logs
Use standard getRequestURI() instead of Jetty internal getHttpURI(),
which apparently changed somewhere along the way

Hide Jetty ClosedChannelException from I2P logs
2021-01-13 08:54:46 -05:00
zzz
bf29132898 Tunnels: Downgrade log error to warn 2021-01-12 09:49:09 -05:00
zzz
a424331b78 i2psnark: Don't decrement downloaded counter after receiving bad piece
Received reports of counter going negative
2021-01-12 08:23:36 -05:00
idk
ccb0c279f7 Fix the width of the custom options at the bottom of i2ptunnel on the light theme 2021-01-11 12:48:07 -05:00
zzz
7fe01fb9a7 Console: Delete rrd files for no-longer-configured stats at startup 2021-01-11 10:21:54 -05:00
zzz
66c4c10a78 Console: Improve parsing of email address (part 2) 2021-01-10 08:03:15 -05:00
zzz
163967311e Console: Improve parsing of email address for mailto: link on /plugins 2021-01-10 07:24:28 -05:00
zzz
75734448c5 I2NP: Stub out new tunnel build messages (proposal 157)
WIP - not hooked in yet
2021-01-09 12:00:18 -05:00
zzz
aed1de84b8 SSU: Fix bandwidth estimator deadlock (ticket #2798)
Fix logging in SBE (bytes not packets)
2021-01-08 12:07:41 -05:00
zzz
51560a8ec8 i2ptunnel: Disable shared clients (DSA) (part 2)
missed case in 2020-12-29 checkin
2021-01-08 11:27:53 -05:00
zzz
ec89a80e80 Router: Disable reseeding and NTP in vmCommSystem 2021-01-07 11:04:56 -05:00
zzz
41c7b7382a SSU: Implement fast retransmit (ticket #2427)
This partially fixes the issue of packets not being retransmitted
before they expire in 10 seconds, introduced in 0.9.48 as reported by
jogger at http://zzz.i2p/topics/3003
Fast retransmit was also suggested by jogger as a solution and discussed in that thread.
This code is based on the requirements for TCP fast retransmit
as specified in RFC 5681 but cannot precisely follow the RFC
as UDP messages can be dropped without affecting later messages:
- nack counter is per-message, not per-connection
- some interactions with the retransmit timer when in fast retx mode
- msg expiration is currently 10s but max RTO is 60s
- interactions with individual fragment transmission implemented in 0.9.48-5
- this is a sender-side fix but it depends on far-end ack resend strategy

Maintain a local message sequence number and store
it in OMF, previously unused as codel is disabled
Removed acked messages from _outboundMessages as usual,
but stores message and seq. numbers in a LinkedHashMap,
so we may interpret additional acks as nacks.
Calculate the highest-acked seq. number for every incoming packet.
Marks messages older than highest acked as nacked
Fast-retransmits after 3 nacks
Window and SST adjustments per RFC 5681 sec. 2.4
Reduce resend ack quantity and timeout to improve odds of receiving "nacks"
Disable wakeup of OMF from IMF; should not be needed now that PS calls nudge()
PS.acked(partial) now returns true if any fragment was acked, not if complete
Log tweaks

Still todo: possible additional changes to ack resend strategy;
possible parameter adjustments including msg expiration;
confirm that OMF wakeup in IMF is not required;
further testing and cleanups;
take additional ideas from alternative proposal in MR !8;
stat tweaks;
find related tickets to close

Reviewed by and contains code from zlatinb in MR !8
This builds on several previous SSU improvements; see #2427 for a list.
ref: gitlab MRs !8 !9 !10 !11
2021-01-07 09:33:09 -05:00
idk
b4e1fbd857 center the text on the force restart and shutdown buttons in the sidebar 2021-01-06 16:25:07 -05:00
zzz
517ff4fa24 i2psnark: Add ability to remove I2CP options
Properly lock options map
Remove unused configured variable
2021-01-05 11:21:04 -05:00
zzz
106b1a696d SusiDNS: Hide last-modified on details page if empty 2021-01-05 09:22:36 -05:00
zzz
6cab545c45 Console: Reduce limit of concurrent graph generation on slow devices 2021-01-05 09:18:25 -05:00
zzz
619923dbf8 Build: Update external javadoc links
Add description to gradle update tasks
Add note about jetty versions
2021-01-04 11:51:24 -05:00
zzz
ed0ecdf253 Build: Add gradle updater tasks 2021-01-04 09:36:34 -05:00
zzz
d42ef2223d Build: Add i2pcontrol and imagegen to gradle build 2021-01-04 08:34:09 -05:00
zzz
e461004ed9 Build: Remove jars from gradle wars 2021-01-04 07:38:19 -05:00
zzz
2e180d4c60 Build: Add translations to gradle build (part 3 - only rebuild if necessary) 2021-01-03 10:35:04 -05:00
zzz
152ad1659b Build: Add translations to gradle build (part 2 - wars)
Several fixes for i2ptunnel gradle build
2021-01-03 09:55:42 -05:00
zzz
888311e34f Build: Add translations to gradle build (part 1 - jars) 2021-01-03 09:08:21 -05:00
zzz
2df5fb972a Sybil: Reduce default threshold 2021-01-02 09:58:08 -05:00
zzz
a481255adb Tunnels: Improve error handling of zero tunnel ID at OBEP
Reduce max time to defragment
Make logging of errors consistent
cleanups, stat tweaks
2021-01-02 09:57:27 -05:00
idk
139594df8f Move travis test runner script to own file so it's easier to work with 2021-01-02 09:12:02 -05:00
idk
659ab97f69 Try increasing sonar scanner heap size in travis builds 2021-01-02 08:49:46 -05:00
idk
963a4fe89c Extend travis timeout and make sonarqube output verbose 2021-01-02 08:39:21 -05:00
zzz
4c4dbae107 Console: Show file mod time in local time zone on /jars 2021-01-01 11:05:04 -05:00
zzz
6978049416 Console: Link to our gitlab on /jars 2021-01-01 10:49:14 -05:00
zzz
46fe1ba74a Build: Gradle fixes
Add resources to jars and wars
remove .jsi and .jsp files from wars
remove classes that are in jars from the wars for apps that have both
compile jsps in routerconsole.war
build routerconsole.jar
2021-01-01 10:17:00 -05:00
zzz
13bd5e4938 SSU: Remove router version check for random intro key, now that the release is out 2021-01-01 07:13:26 -05:00
idk
bbacf85245 travis-ci test: correct the sonarqube version for the last time, I think 2020-12-31 15:38:24 -05:00
idk
68f011f344 Remove some CSS that applies to images that aren't present in the current software. Also switch to version 2.8.0 of sonarqube in travis.yml since 3.0.0 does not seem to be available as a gradle plugin for this version 2020-12-31 15:31:52 -05:00
idk
8bd2384ac8 travis-ci test: Try updating the sonarqube plugin. 2020-12-31 13:05:26 -05:00
zzz
54dda1a15f alignment 2020-12-31 12:47:01 -05:00
zzz
3f44a555ba Console: Use local time on graphs by default, add UTC option 2020-12-31 12:36:07 -05:00
idk
86cbb2ed4e travis-ci test: Try switching to oraclejdk11 without updating the sonarqube plugin. 2020-12-31 11:52:10 -05:00
zzz
2569123055 NetDB: Drop lookups with replies going to us
Extend lookup expire time
Cleanups
2020-12-31 08:37:04 -05:00
idk
afa4b9e66d Tweak border color on /events form 2020-12-30 18:34:42 -05:00
idk
67bd5a32fd fix overlapping border on /events css, closes #4 2020-12-30 18:32:57 -05:00
idk
ada3629507 correct name of git-bundle ant target 2020-12-30 15:38:47 -05:00
idk
dcb7314306 travis-ci now requires you to use trusty if you also want to use oraclejdk8 2020-12-30 14:50:09 -05:00
idk
e3c2ad6354 fix broken travis test 2020-12-30 14:14:30 -05:00
idk
178ea252d5 Merge branch 'bundle-target' into 'master'
add a bundle target to ant that generates a current git bundle and corresponding torrent.

See merge request i2p-hackers/i2p.i2p!1
2020-12-30 15:49:41 +00:00
idk
7e4ba4eb31 Merge branch 'master' into 'bundle-target'
# Conflicts:
#   build.xml
2020-12-30 15:48:58 +00:00
zzz
de43de17f6 Crypto: Only skip N mixHash for router messages
Still required for ECIES build replies; previous checkin broke it
Make a new pattern id for N without responses
Fixes ECIES build replies
2020-12-30 07:08:47 -05:00
zzz
2ceb9c429a Console: Add tunnel nicknames to router debug page
Escape tunnel nicknames on LS debug page
2020-12-29 16:29:53 -05:00
zzz
0b59f53fe9 i2ptunnel: Disable shared clients (DSA), any server not
supporting EdDSA doesn't support LS2.
2020-12-29 15:51:51 -05:00
zzz
62fce859b9 Ratchet: mixHash() not required after message for N pattern 2020-12-29 14:15:00 -05:00
zzz
9fc97764c5 NetDB: Verify RI stores for a while after starting 2020-12-29 14:06:28 -05:00
zzz
2813d9412d Crypto: Cache AES Ciphers
About a 10% speedup
2020-12-29 10:26:41 -05:00
zzz
a0bf76a4b1 Debian: Add JRE 15,16 2020-12-28 08:29:07 -05:00
zzz
d2a79e8837 Build: Add version where missing from jar manifests 2020-12-28 08:07:50 -05:00
zzz
738ef496d4 Debian: Build fix for no geoip files 2020-12-27 10:13:02 -05:00
zzz
a2734ffa72 SSU: Fix restoration of window after failed message
Reported by and adapted from patch by zlatinb
2020-12-27 08:50:11 -05:00
zzz
8606d30e9a Build: Fixup installer build after flags move 2020-12-26 10:28:37 -05:00
zzz
a45084cfc3 Console: Move initial news to jar 2020-12-26 10:13:49 -05:00
zzz
eeaf6f3514 Console: Fix missing newlines in readme output 2020-12-26 09:36:36 -05:00
zzz
9e18ff1cd1 Router: Move countries.txt file into i2p.jar 2020-12-26 09:33:13 -05:00
zzz
665239fd37 Router: Move continents.txt file into jar
Move core resources directory to be consistent with the other subsystems
2020-12-26 08:11:00 -05:00
zzz
12f9a7187e Console: Move flag overrides to war 2020-12-26 06:12:31 -05:00
zzz
8835351b99 I2CP: Fix requesting leasesets for subsessions (ticket #2458)
Always request new LS for subsessions also
Don't reuse LS object for subsessions
Cancel rerequest timer as necessary
Fixes watchdog warnings
Fixes console status for subsessions in different states
javadocs
2020-12-24 13:56:32 -05:00
zzz
a3c44912f2 SusiDNS: Fix link to backup image 2020-12-24 10:11:41 -05:00
zzz
db9f735376 i2ptunnel: Fix writing config file twice on saving existing tunnel
Fix 'Invalid tunnel number' message on saving new tunnel
javadocs
log tweaks
2020-12-23 12:26:56 -05:00
zzz
875a7242d4 Javadoc update for DoH 2020-12-23 10:22:34 -05:00
zzz
51ecdc64a4 Debian: Refresh json patch 2020-12-23 10:18:29 -05:00
zzz
7b785ea454 I2CP: Fix encrypted leaseset for ECIES and dual-key encryption, and for offline keys 2020-12-23 10:05:58 -05:00
zzz
8f5fc44755 Crypto: Increase ratchet tag window
Set trimbehind = lookahead
Ramp up tag window faster
Check for ratchet ES encrypt fails
Log tweaks
2020-12-23 06:47:39 -05:00
zzz
010dbfa6f2 Console: Move resource helper to war, doesn't work from jar 2020-12-22 12:37:47 -05:00
zzz
e20a19c358 Console: Move readme files to war 2020-12-22 09:50:02 -05:00
zzz
387e513949 Console: Add netdb search by enc. type 2020-12-22 07:36:47 -05:00
Zlatin Balevsky
5e005e6520 Merge branch 'whitespace' into 'master'
Whitespace

See merge request i2p-hackers/i2p.i2p!7
2020-12-21 23:00:12 +00:00
Zlatin Balevsky
e88f40cd95 Whitespace 2020-12-21 23:00:12 +00:00
zzz
82e93a53a3 bump -7 2020-12-21 15:51:14 -05:00
zzz
fee5668c1c Merge branch 'partial-ack-fix' into 'master'
SSU: Fix partial acks not being sent when there are no 'gaps'.

See merge request i2p-hackers/i2p.i2p!6
2020-12-21 20:47:11 +00:00
zzz
abb8cbe75d SSU: Fix partial acks not being sent when there are no 'gaps'.
Workaround the bug on the sending side for pre-0.9.49 routers by sending fragments in reverse order.

Bug introduced in commit 9c4558d891 Sep 20 2014.
This partially reverts that commit.
Reported by and adapted from a patch by zlatinb
2020-12-21 10:02:20 -05:00
zzz
340df51429 Console: Fix theme selection 2020-12-20 14:40:09 -05:00
zzz
bec8feb05a Build: Fix up proxy file location 2020-12-20 14:08:13 -05:00
zzz
d86ccded53 Proxy: Move error page resources to jar 2020-12-20 13:50:54 -05:00
idk
db7d92a5cd Apply 1 suggestion(s) to 1 file(s) 2020-12-20 17:57:52 +00:00
zzz
30ffdd03c7 SSU log tweaks 2020-12-20 08:35:07 -05:00
zzz
251d8de943 Merge branch 'wplus-wip' into 'master'
SSU: Westwood+ congestion control (ticket #2427)

See merge request i2p-hackers/i2p.i2p!4
2020-12-20 13:13:34 +00:00
zzz
5e8de68746 SSU: Increase sendWindowBytesRemaining when increasing the window
Fix BWE log formatting
2020-12-19 08:23:13 -05:00
zzz
8ae29c8c00 SSU: Westwood+ bandwidth estimator classes (ticket #2427) 2020-12-19 07:26:53 -05:00
zzz
542efa0d9a SSU: Westwood+ congestion control (ticket #2427)
Reduce initial window to match RFC
Add back to window on message failure
Remove two bps stats
log tweaks
2020-12-18 14:46:26 -05:00
zzz
23c80accfa SSU: More PeerState cleanup 2020-12-18 11:58:55 -05:00
zzz
b909430725 SSU: Account for packet overhead in window calculations 2020-12-18 11:52:18 -05:00
zzz
20b413bc67 Crypto: Fix use after free (ticket #2797) 2020-12-18 11:05:36 -05:00
Zlatin Balevsky
a9b6b86183 Merge branch 'ssu-sync-fix' into 'master'
lock locked_shouldSend on this

See merge request i2p-hackers/i2p.i2p!3
2020-12-18 13:48:40 +00:00
Zlatin Balevsky
66b724759d lock locked_shouldSend on this 2020-12-18 09:03:52 +00:00
zzz
56059448c5 SSU: Send subset of fragments (ticket #2427)
if all fragments will not fit in the window.
Track per-fragment send count.
Reset send window when retransmitting.
Update send window when partial acks received.
Make OMS.getMaxSends() and getPushCount() track different things.
Change OMS.push() to be called by OMF and return the pushed fragments.
Use size of smallest fragment rather than total size to determine if we can send a message now.
This is an improved fix for ticket #2505.
Eliminate repeated calls to OMS.getLifetime()
Log tweaks and reduce log levels
Improves throughput on lossy connections.
Reduces latency for large messages.
This is prep for reducing DEFAULT_SEND_WINDOW_BYTES and W+, which
would have exacerbated these issues.
Additional changes to follow, implementing Westwood+, see #2427
2020-12-17 12:54:24 -05:00
zzz
1c52eeb910 NetDB: Prevent reported NPE 2020-12-16 11:01:45 -05:00
zzz
4aefe4bf7a SSU: Fix OMF looping when timer isn't cancelled after last message acked
Push out timer when no more bandwidth available
Workarounds for now, more changes to follow
2020-12-16 09:40:39 -05:00
idk
b9444cdc51 Merge branch 'fix-ides' into 'master'
Fix ides

See merge request i2p-hackers/i2p.i2p!2
2020-12-14 23:22:16 +00:00
idk
eb72e4c9f5 remove padding from control buttons on i2ptunnel in order to recenter the text vertically 2020-12-14 12:18:19 -05:00
zzz
aa181ee43f SSU: Restore sync dropped in cleanup 2020-12-12 11:00:03 -05:00
zzz
ab04f92072 SSU: PeerState cleanup 2020-12-12 10:15:02 -05:00
zzz
0830329eaf Build: delete file after building to make git happy 2020-12-12 10:13:56 -05:00
Zlatin Balevsky
2d154cc90e update gitignore 2020-12-11 20:21:10 +00:00
Zlatin Balevsky
183280871f get gradle assemble to work 2020-12-11 20:12:27 +00:00
Zlatin Balevsky
067ee80ba0 remove IntelliJ and Eclipse project descriptors 2020-12-11 19:45:25 +00:00
idk
804e2f39f9 append full version to git bundle generation when generating from the ant target 2020-12-11 13:51:40 -05:00
zzz
0ad7e52b71 Router (proposal 156):
- Change router ECIES SKM to use N pattern, remove Elligator2, to match proposal changes
- Allow encrypted messages to ECIES routers
- Allow ECIES routers to become floodfill
- Add XDH factory to VM comm system for tests
2020-12-11 10:08:41 -05:00
zzz
e15110bbe1 Build: Fix i2pcontrol unset property in manifest 2020-12-11 09:00:12 -05:00
idk
2cffda6974 update the HACKING.md to reflect better and/or git-based instructions, also a test commit for git migration. 2020-12-10 13:42:02 -05:00
zzz
2300f6c226 i2psnark: Add web seeds in TrackerClient
list web seeds in UI
2020-12-06 14:25:43 +00:00
zzz
1ed8a1b6f3 i2psnark: Close RAF on error 2020-12-06 14:13:10 +00:00
zzz
c4ed7719e8 i2psnark: Preserve file attribute strings in metainfo 2020-12-06 14:00:02 +00:00
zzz
a98fe45204 Streaming: Add Retry-After header to throttle response 2020-12-06 13:26:55 +00:00
zzz
5a3e26453f Transport: Block SIP ports 2020-12-06 13:11:46 +00:00
zzz
c259000cdb Console: fixup param name 2020-12-06 13:09:57 +00:00
zzz
d683f0d9eb Util: Change DoH to the RFC 8484 protocol 2020-12-06 12:54:20 +00:00
zzz
48b8886224 i2psnark: Add WebSeed support - WIP - not hooked in yet 2020-12-06 12:43:55 +00:00
zzz
1097220d31 i2psnark: Move URIUtil from war to jar (prep for WebSeed) 2020-12-06 12:37:19 +00:00
zzz
fdeae72d38 i2psnark: Fix up standalone build 2020-12-06 12:31:22 +00:00
zzz
f870bc2ccd console: Move web resources to war 2020-12-06 12:05:53 +00:00
zzz
ec3bfa3cb7 susimail: Move web resources to war 2020-12-06 12:03:27 +00:00
zzz
c3f7c5d154 susidns: Move web resources to war 2020-12-06 12:02:11 +00:00
zzz
127b93c1e2 i2ptunnel: Move web resources to war 2020-12-06 11:59:54 +00:00
zzz
cd019f258f i2psnark: Move web resources to war 2020-12-06 11:59:11 +00:00
zzz
889b7361fe imagegen: Move CSS to war 2020-12-06 11:55:40 +00:00
zzz
99f6d4aba4 MiniDNS javadoc fix 2020-12-05 14:27:56 +00:00
zzz
69deddcbc7 Add DNS library to support RFC 8484 DoH (ticket #2201)
WIP - not yet hooked in

This is a portion of release 1.0.0 of MiniDNS from https://github.com/MiniDNS/minidns/ 2020-07-18
Only contains the minidns-core portion of the library.
Removed tests, most util classes, and DnsRootServer class.
Unmodified, as a base for future checkins.
Total size of zipped classes is about 75 KB.

This software may be used under the terms of (at your choice)
- LGPL version 2 (or later)
- Apache Software licence
- WTFPL
2020-12-05 14:21:08 +00:00
zzz
58020b4b58 Console: Swap some columns on ssu /peers for consistency
Format send window and slow start threshold values
2020-12-05 12:56:58 +00:00
zzz
df43e72a08 PRNG: Drop unused exception and interface 2020-12-05 12:51:24 +00:00
zzz
326e2c630c Debian: Files for 0.9.48
refresh patches
update release docs
2020-12-02 14:53:38 +00:00
zzz
36fdfd529f 0.9.48 2020-12-01 15:54:41 +00:00
zzz
94bdc9c5b3 Late pl,zh translation updates 2020-12-01 14:50:37 +00:00
zzz
c60e51514c Add old cert to deletelist.txt
Javadoc fix
2020-12-01 14:39:44 +00:00
zzz
7dcbbf17c3 Console: Fix headers on /debug
JS: Update license headers
patch from idk
2020-12-01 14:36:50 +00:00
zzz
5551deb246 pull RU translations 2020-11-28 19:42:22 +00:00
zzz
6e8fd42efd pull translations 2020-11-27 18:40:53 +00:00
zzz
5020100ef8 BuildTime update 2020-11-27 18:06:55 +00:00
zzz
6c2c6abfb9 NTCP: Enable nodelay by default
SSU: Don't wakeup OMF after ack if no more messages are pending
2020-11-26 18:58:22 +00:00
hankhill19580
4940c34779 More light theme CSS tweaks to table headings and table spacing on /config*, switch from uppercase to capitalize for titles on SusiMail 2020-11-25 03:58:38 +00:00
hankhill19580
6d5aebeaa0 remove borders from around notifications on /welcome 2020-11-24 19:27:02 +00:00
zzz
d8924119b5 NTCP: Add nodelay option for testing 2020-11-24 14:48:59 +00:00
zzz
4b445e7d35 Build: release target fixes for git 2020-11-24 14:45:02 +00:00
zzz
17e47a0c93 Build: revisions target for git 2020-11-24 14:02:20 +00:00
zzz
2ffb570850 Console: Serve default favicon.ico
i2ptunnel: Remove dup link to nonexistent theme favicon.ico
2020-11-23 18:46:12 +00:00
zzz
aef2fb8ce0 i2pcontrol: Basic HTML fixes and HTTP headers for static pages 2020-11-23 15:24:19 +00:00
zzz
875fcdfb94 NetDB: Increase min FF version for LS lookups since most are LS2 now 2020-11-22 19:46:18 +00:00
hankhill19580
151f856b0a apply revert to h3#transports on /peers to fix cramping 2020-11-22 16:25:15 +00:00
zzz
337787be0e i2psnark: Remove old opentrackers 2020-11-21 17:27:41 +00:00
zzz
798521466d Proxy: Remove old jump servers 2020-11-21 17:24:24 +00:00
zzz
678c035fa3 Proxy: Fix CSP for conflict error page 2020-11-21 17:21:36 +00:00
zzz
ccb4210f8b NetDB: Limit max explore at startup when hidden 2020-11-20 14:37:22 +00:00
zzz
7e5dc6ad64 Tomcat 9.0.40 2020-11-20 14:11:59 +00:00
zzz
31622d0458 NetDB: Increase exploration rate when hidden 2020-11-20 12:59:22 +00:00
zzz
f9b18545f9 Reseed update 2020-11-20 12:30:52 +00:00
hankhill19580
e67eccd1eb Remove inconsistent gradients from light theme /config items 2020-11-19 22:25:51 +00:00
hankhill19580
cefe212a17 Get rid of uppercase text transforms on non-table headings, fix wierd white background on h4's 2020-11-19 21:44:11 +00:00
hankhill19580
8a76d71bd5 Widen margins in langsettings dropdown 2020-11-19 21:11:04 +00:00
hankhill19580
806df95114 Lighten up some borders on /home, improve consistency of backgrounds on /home, header margins on apps on homepages 2020-11-19 20:56:21 +00:00
hankhill19580
c6c0b9ce8a Un-squish the SusiDNS SVG image on Firefoxes greater than 83, remove wierd padding from .optboxes 2020-11-19 18:27:29 +00:00
zzz
00a0970c95 Crypto: Adjust Java key cache sizes 2020-11-19 14:52:11 +00:00
zzz
cb1bd95f2b Build: Reproducible build fix (ticket #2279) 2020-11-19 14:28:38 +00:00
zzz
d12b52f82a Debian: Clean up old commented-out rules 2020-11-19 12:53:26 +00:00
zzz
891ffaac09 Update apparmor profile for usrmerge
https://bugs.launchpad.net/ubuntu/+source/i2p/+bug/1784023
2020-11-19 12:42:07 +00:00
zzz
36fbf0e332 poupdate-source 2020-11-18 17:54:36 +00:00
zzz
e811238d60 NetDB: Disable sending encrypted messages to ECIES routers for now
The #ls2 team plans to change the specification and re-enable after the 0.9.48 release
2020-11-17 16:21:10 +00:00
zzz
c9e6bef825 Jetty: Patch to fix console not starting on Java 11.0.9.1
Backport JavaVersion.java from Jetty 9.4.34
Jetty does not plan to fix in 9.3.x
ref:
https://github.com/eclipse/jetty.project/issues/5682
https://github.com/eclipse/jetty.project/issues/2284
http://zzz.i2p/topics/2991
2020-11-17 15:50:10 +00:00
zzz
0f002b9b69 Jetty 9.3.29.v20201019/ 2020-11-17 15:39:08 +00:00
zzz
f179a057bc Wrapper: Add missing binaries for armv7 and aarch64 to installer (ticket #2308) 2020-11-17 12:04:49 +00:00
zzz
6f5042be8f Test: Drop ancient unused DateMessage 2020-11-16 16:16:49 +00:00
zzz
2044474549 Zxing: Update to 3.4.1 (2020-09-29)
Merge in javadoc fixes
2020-11-16 15:55:27 +00:00
zzz
0b0b93f26f javadoc fix 2020-11-16 15:32:29 +00:00
zzz
595f8762ab I2NP: Don't extend DataStructureImpl, to save space
Fixup test as required
2020-11-16 14:51:35 +00:00
zzz
8644eb431e GeoIP 2020-11-01 2020-11-16 14:43:22 +00:00
zzz
223afdfc7e Wrapper: Update to wrapper 3.5.44
All binaries from Tanuki Delta Pack Community Edition,
except for armhf (armv6), compiled on Raspberry Pi:
  ant 1.8.2
  javac 1.7.0_151
  gcc 4.6.3-14+rpi1

Windows binaries remain unchanged as we must recompile them ourselves
(32 bit just to change the icon; 64 bit is not provided by Tanuki)

PPC 32-bit big endian not updated, no longer supported by Tanuki
2020-11-16 14:35:48 +00:00
zzz
de41cab08e GarlicClove: Store time as long rather than Date to save space 2020-11-11 16:00:57 +00:00
zzz
3606a42ea8 Lease: Store time as long rather than Date to save space
Add long methods, deprecate Date methods
2020-11-11 15:15:44 +00:00
zzz
6887c7edae I2CP: Don't have I2CP Messages extend DataStructureImpl, to save space
Ditto MessageId and SessionId.
Fixup unit tests as required
2020-11-11 13:09:42 +00:00
hankhill19580
4a00691385 increment the counter on the bandwidth config page by 5 instead of 10 so that it can actually match the recommendations on the /welcome 2020-11-11 00:32:35 +00:00
hankhill19580
1d0a2c4fac Fix right-side padding of down arrow on select boxes 2020-11-10 19:40:30 +00:00
hankhill19580
d0016380e5 Make all the border radiuses consistent across apps. Button-like inputs get a 12px radius, text-like inputs get a 6px radius. "Professional but not prickly." nix almost all drop-shadows and most text-shadows. more 1-3 pixed tweaks to get text centered up 2020-11-10 19:15:41 +00:00
zzz
29dc311c6a Ratchet: Destroy HandshakeState after fatal NS/NSR errors 2020-11-10 15:22:46 +00:00
zzz
7aa78a1aed One more i2cp buffer size increase 2020-11-10 14:57:39 +00:00
zzz
989f64192f i2psnark: Larger read buffer for large files 2020-11-10 14:54:37 +00:00
zzz
c908c6bd05 Data: SDS no longer extends DataStructureImpl to save space
More minor i2cp efficiency improvements
KeyCertificate log tweak
2020-11-10 14:48:42 +00:00
hankhill19580
9f51b72cab fix oversized button on i2ptunnel home page 2020-11-08 02:49:16 +00:00
zzz
a2fd817915 Tunnels: getUnknownOptions() is non-null
one more TunnelId fixup
2020-11-07 13:53:44 +00:00
zzz
5bafdd05a9 Tunnels: Simplify TunnelId and HopConfig to save space
and reduce object churn and duplication
Fixup tests, javadocs, logging as required
2020-11-07 13:40:48 +00:00
hankhill19580
e18708bdbe round and re-center buttons on i2ptunnel home page 2020-11-07 07:18:15 +00:00
hankhill19580
f6687c1f88 add a little padding to the left of the text in the sidebar under Local Tunnels, set links list style to none instead of using the link image 2020-11-07 02:55:35 +00:00
hankhill19580
b9eabca403 use paste.png for the pastebin instead of pasteidk.png so in theory other pastebins could use it 2020-11-06 16:59:30 +00:00
hankhill19580
9ec2c62f2f update the contents of /home to include git.idk.i2p and paste.idk.i2p 2020-11-06 16:57:47 +00:00
zzz
d4152ea546 NetDB: Ensure RI republish time is less than validation time
to prevent failures on connections esp. for hidden mode
2020-11-05 18:47:49 +00:00
zzz
8cc62b5b42 Util: More elimination of data copies 2020-11-04 14:27:16 +00:00
zzz
e242015145 Util: Hook in ByteArrayStream
Set accurate lengths for zero-copy
2020-11-04 12:04:24 +00:00
zzz
35da97936d Point to gitlab in console readme.html,
as approved at today's meeting
2020-11-03 20:59:39 +00:00
zzz
bfe21176ea Add host already linked in console,
as approved at today's meeting
2020-11-03 20:30:53 +00:00
zzz
d1dd9ab517 i2ptunnel: Add checks for offline expiration in alternate destination
Improve logging for expiration checks
2020-11-03 16:39:35 +00:00
zzz
c18dbe974a Remove reseed SSL cert, now using a CA 2020-11-02 22:19:49 +00:00
zzz
f69563da75 Util: New zero-copy BAOS
WIP, to be hooked in
2020-11-02 12:12:20 +00:00
zzz
057eca56d5 Console: Show offline expiration on LS debug page 2020-11-02 12:01:58 +00:00
zzz
a21a64e0c6 i2psnark: Remove unused bencode() methods 2020-11-02 11:39:40 +00:00
zzz
751af5bcd8 i2psnark: Limit max size of embedded video 2020-11-02 11:33:34 +00:00
zzz
c8605009ba i2ptunnel: Automatically restart tunnel if offline-signed private key file is updated
Periodically log if about to expire
Short delay between stop and start on restart
_tunnel is always non-null
2020-11-02 11:27:06 +00:00
zzz
5625caebda I2CP: Remove tunnels immediately on client disconnect 2020-11-02 11:21:52 +00:00
zzz
fc0a78dd7b Util: Drop class deprecated 11 years ago 2020-10-31 20:20:59 +00:00
zzz
90aab37002 i2psnark: Add support for comment and url_list to Storage CLI
Add support for multiple urls to MetaInfo CLI
Add comment to release torrent
2020-10-30 16:37:54 +00:00
zzz
5c1a529df0 Util: Fix NPE in EepGet CLI callback via PartialEepGet
Fix callback javadocs
2020-10-30 15:22:24 +00:00
zzz
6fa015c410 i2psnark: MetaInfo support for url-list (prep for BEP 19),
WIP - unused for now.
Add url-list to CLI tool for testing
Add comment support to CLI tool
2020-10-30 13:18:46 +00:00
zzz
2d1e68b53b i2psnark: Store BEP 47 padding file info in a bitmap (prep for BEP 52),
WIP - unused for now.
Don't instantiate files_utf8 unless needed, which it never is
2020-10-29 17:13:32 +00:00
zzz
35012a3bad Crypto: Precalculate Noise init hash 2020-10-29 16:51:13 +00:00
zzz
190b76d7fd Tunnels: Improved logging and handling of offline signature expiration
Store back ref to controller in tunnel
Stop server controller on I2PException
Support generation of keys with fractional days expiration for testing
2020-10-29 15:20:56 +00:00
hankhill19580
8d0b1214d2 un-do android check in ObjectCounter and fix hte issue by correctly setting the classpath instead, see RELEASE-PROCESS.md in i2p.android.base 2020-10-29 04:04:18 +00:00
zzz
70eb2a49f9 Router: Fix ECIES tunnel testing part 2
Remove ratchet tag from RSKM on timeout
2020-10-28 13:15:26 +00:00
zzz
f231ea0951 Util: ObjectCounter better android detection 2020-10-28 12:09:55 +00:00
zzz
f9ffdd5137 Router: Fix tunnel testing for ECIES routers 2020-10-28 12:04:01 +00:00
hankhill19580
38f9955391 fix android keySet bug that I discovered this morning 2020-10-28 04:33:47 +00:00
zzz
517ff9af28 Build: Fix dev info in maven data 2020-10-27 15:30:03 +00:00
zzz
62a91acb40 DoH: Limit response size, sort servers for test
SSLEepGet: Fix handling of state param, support max size param
2020-10-27 14:53:11 +00:00
zzz
69a5266675 DoH: Add CLI test of all servers 2020-10-27 12:45:37 +00:00
zzz
e671741329 DoH: Set user agent 2020-10-26 22:47:32 +00:00
zzz
ab55f27ea4 DoH: Add more CLI options for testing 2020-10-26 15:29:59 +00:00
zzz
cf88b3057a DoH: limit total time and max requests
Better loop checking, force DoH off for request
2020-10-26 13:44:23 +00:00
zzz
af97eedcbb Util: Fix EepGet allowCaching parameter
Add SSLEepGet method to force DoH on/off
2020-10-26 12:22:54 +00:00
zzz
7823001594 BOB: Add deprecation warnings 2020-10-25 12:31:50 +00:00
zzz
a49f87179a Router: Quick checks of eph. key MSB before Noise DH
Additional checks on ECIES BRR to catch old/buggy routers
Detailed logging of ECIES BRR decrypt fails
2020-10-25 10:55:53 +00:00
zzz
b52f85ac38 Tunnels: Add missing expiration field to ECIES BRR 2020-10-23 19:42:05 +00:00
zzz
470bc77551 fix one more ;; 2020-10-23 16:10:58 +00:00
zzz
a0822a6b71 NTCP2: Reduce min downtime for rekeying if hidden 2020-10-23 16:09:15 +00:00
zzz
15da2f85ad SSU: Minor cleanup of congestion checkin 2020-10-23 16:05:39 +00:00
zzz
9b3ff9e615 TCG: Rename method to reflect what it really does 2020-10-23 16:03:19 +00:00
zzz
df1db163f0 i2ptunnel: Remove mtn tunnel (new installs only) 2020-10-23 15:50:30 +00:00
zzz
4a4d814a17 Tunnels: Move AES reply keys from HopConfig to TunnelCreatorConfig
to save space; not stored for participating tunnels.
2020-10-23 12:58:45 +00:00
hankhill19580
c84360ba4b Update the Firefox user-agent string to match the Firefox ESR that is currently used in Tor Browser, credit to dr|zed for pointing out the update and the fix. Tor Browser updated to Firefox ESR 78 with the 10.0 release on September 24, 2020 2020-10-22 16:12:26 +00:00
zzz
6a6064d614 Garlic: Reduce log level on misrouted message 2020-10-21 20:24:12 +00:00
zzz
49565a99f9 SSU: Redesign of the congestion control (tickets #2412, #2649, #2654, #2713),
modelled on TCP Reno (RFCs 5681 and 6298)
- Use a single timer per connection
- Resend up to half the un-acked messages per timer event instead of a single message
- Only send either old or new messages, do not mix
- Cache/avoid several timer calls
- Instead of 3 return values, allocating bandwidth is now a boolean function
- Avoid one of the iterations over all un-acked messages every packet pusher loop
- Remove 100 ms failsafe
- Fix OMF debug log NPE
With the same cpu usage the bandwidth is much higher
Significant speed improvement for lossy connections (e.g. wifi)
Patch by zlatinb
2020-10-21 18:14:51 +00:00
zzz
ee27bc3bbf Reseed: Renew SSL cert expiring soon 2020-10-21 15:21:41 +00:00
zzz
25899d41d5 NetDB: ECIES router support (proposal 156):
Support sending encrypted lookups and stores to ECIES routers
Support requesting AEAD replies to ECIES routers
Encrypt RI lookups when using ECIES even on slow machines
Switch back to RatchetSKM
Don't schedule ack timer for router SKM
Reduce getContext() calls
GMB null check cleanup
MessageWrapper javadoc clarifications
Log tweaks
2020-10-21 14:54:47 +00:00
zzz
35f6a2e2bf NetDB: Reseed after a long downtime 2020-10-21 13:46:31 +00:00
zzz
9ae5cbbc87 SSU: Increase socket buffer size (ticket #2781) 2020-10-21 12:44:27 +00:00
zzz
0ace93cec7 i2psnark: Remove references to "maggot" links 2020-10-17 15:19:23 +00:00
zzz
d387448794 ;; -> ; 2020-10-17 14:41:13 +00:00
zzz
4d82917b94 SSU: Fix calculation of nextSendDelay (ticket #2714)
patch from zlatinb
2020-10-17 12:12:15 +00:00
hankhill19580
7a77f48963 Work on lining up some of the button text and icons a little better, fix peer icon and top/bottom icon, various padding issues 2020-10-16 04:55:48 +00:00
zzz
dee5dfc682 clear exec bit 2020-10-15 15:48:39 +00:00
zzz
5ed6f834c1 libjbigi for linux aarch64 (ticket #1840)
stripped
gcc: 7.5.0
jdk: openjdk version "1.8.0_265"
Built on: Raspberry Pi 4 Model B Rev 1.4
Add support to mbuild-all.sh
2020-10-15 15:36:38 +00:00
zzz
3b8e5f0763 i2psnark: Stub out BEP 52 message numbers
Hide BEP 48 padding directory from UI
Check for and reject BEP 52 info multihashes for now
Use cached fai.isDirectory for efficiency
Use storage.getFileCount() instead of meta.getFiles() to prep for padding files
Add notes for padding file TODOs
2020-10-15 12:04:24 +00:00
zzz
7c1798513d Util: Singleton OrderedProperties comparator 2020-10-15 11:54:43 +00:00
zzz
e54950e02e Router: MessageWrapper.wrap() and GMB support for ECIES (prop. #156 WIP)
NetDB parts still TODO
Remove PK param from GMB.buildECIESMessage(), already in config
2020-10-15 11:50:11 +00:00
zzz
b2f060795c Router: Misc. debug fixes
- StatisticsManager fix for null router in unit tests
- Debug toString() enhancements
- Dest hash logs in b32
- Javadoc fix
2020-10-15 11:39:32 +00:00
zzz
940ad61ccc Ratchet: ECIESAEADEngine main() quick test IK/N NSR 2020-10-15 11:32:25 +00:00
zzz
c1f531ea92 Ratchet: Add support for zero key (prop. #144, WIP for prop. #156) 2020-10-15 11:17:41 +00:00
zzz
0ebca7e8e3 Ratchet: Destroy HandshakeState after NS failure 2020-10-15 11:10:33 +00:00
zzz
d301669726 Router: Don't re-derive public key from private for every HandshakeState 2020-10-15 11:01:22 +00:00
zzz
010bb0a2fe NTCP: Fix sending termination on idle timeout (ticket #2777) 2020-10-12 13:29:46 +00:00
zzz
f028002c11 NTCP: Catch IAE in Reader, possibly a race with cancelled key?
http://zzz.i2p/topics/2968
2020-10-12 13:28:57 +00:00
zzz
11e1747ffc New partial translations for Kurdish, Turkmen, Argentinian Spanish 2020-10-12 12:50:49 +00:00
zzz
5dc9333bb6 DTG: Enable by default for Linux KDE and LXDE
Hide option on /configservice if not supported
2020-10-12 11:24:08 +00:00
zzz
f77acb6db6 i2psnark: Don't truncate 'file not found in torrent' status 2020-10-11 16:25:20 +00:00
zzz
22abf09bd7 i2psnark: Version the file icons
Minor cleanup of icon set selector
2020-10-11 13:22:26 +00:00
zzz
9a1d7a2ae3 Installer: Disable pack200 (ticket #2778) 2020-10-11 12:07:09 +00:00
zzz
98e5908557 i2psnark: Cache length of metainfo 2020-10-10 14:59:13 +00:00
zzz
9e36fe090c Transport: Simplify IPv6 address validation
reject reserved ranges
2020-10-10 12:59:53 +00:00
zzz
b4b6968ede Ratchet debug: Hide expired sessions
Hide sessions with null public key
2020-10-09 13:54:12 +00:00
zzz
999c4c51a2 NetDB: Don't use DSA-SHA1 routers for lookups, stores, or tunnel peers
Don't use non-ElGamal routers for lookups or stores
Prevent DSA-SHA1 routers from auto-floodfill
2020-10-09 13:46:37 +00:00
zzz
8737a6a4fd i2ptunnel: Filter server response headers even if not compressing 2020-10-07 15:02:06 +00:00
zzz
a9a5d13e06 Build: Set javac release property (ticket #2775)
Ant version 1.9.8 or higher now required
Drop support for Xenial package build
Fix up BOB build configuration
Fix i2psnark standalone build
2020-10-07 13:33:41 +00:00
hankhill19580
ca1e2ba91e Switch Snark dark and light themes to using images embedded in the .war, and remove the images substitutions from the filesystem and css 2020-10-07 04:47:27 +00:00
zzz
2e34969bbc Add git hostnames as requested by idk 2020-10-04 16:42:50 +00:00
zzz
cead0b2fb8 Router: Add support for building tunnels through ECIES routers (proposals 152,156)
Preliminary, proposal not finalized, subject to change
Not yet compatibility tested with other implementations
Add peers to match requested length for explicitPeers
remove commented out code
log tweaks
2020-10-03 14:05:22 +00:00
hankhill19580
9d566aea68 snark theme fixes: Revert the i2psnark buttons on the ubergine and vanilla themes back to their original versions, but keep flat buttons for dark and light themes. Fix some squashed icons and apply some slightly better icons for indicating torrent status and contents on dark theme. 2020-10-01 05:01:44 +00:00
zzz
2d9933a4a9 Router: Don't unregister a message without a selector (ticket #2771) 2020-09-28 13:59:30 +00:00
zzz
cd699c587b i2ptunnel: I2Ping CLI tunnel quantity 1
Show current setting for owndest in CLI
Skip a irrelevant log message for I2Ping
Break wait on interrupt
Log level tweaks
2020-09-27 14:38:44 +00:00
zzz
4108007b26 JBigI: Fix zen/zen2/zen3 CPU names (ticket #1869) 2020-09-27 14:33:58 +00:00
zzz
b31b42a557 Streaming: Fix copy/paste errors in tag option handling 2020-09-27 14:17:36 +00:00
zzz
c3f187abcb Console: Drop gateway icon on leasesets page,
just adds clutter with no value.
Change last-changed time on leaseset debug page to use standard formatting
2020-09-26 14:05:29 +00:00
zzz
2989d955d9 JBigI: GMP 6.2.0 for linux 64 bit (ticket #1869)
Add support for zen and zen2
Enable more fallbacks for zen and zen2
Adds Zen and Zen2 binaries, stripped
Built with gcc 9.3.0
Other binaries will be added if testing shows improvement
Fix hangs in mbuild-all.sh build script
Add silvermont and goldmont to build script, untested, support TBD
GMP is GPLv2
More info: http://zzz.i2p/topics/2955
2020-09-26 12:58:55 +00:00
zzz
ea4409897d i2ptunnel: Change enctype default to both for:
HTTP, IRC, and Streamr servers
IRC, SOCKS IRC, and Streamr clients
2020-09-22 14:52:55 +00:00
zzz
7dd7f021b0 Susimail, SAM: More defensive ByteBuffer casting to avoid runtime issues (ticket #2775) 2020-09-22 14:39:32 +00:00
zzz
2cb53ec45c Update LICENSE.txt since SSU HMAC was moved from core to router 2020-09-20 13:48:46 +00:00
hankhill19580
8fa3e45e47 Add tags for librejs compatibility on application/console pages and in embedded javascript 2020-09-20 05:05:57 +00:00
zzz
c4a5d111e7 Build: More git support for release and Debian targets 2020-09-18 14:31:24 +00:00
zzz
dca45a9b18 i2psnark: Defensive checks for v2 format files and magnet links 2020-09-16 14:42:11 +00:00
zzz
6ffebbd5c1 GeoIP: Notify blocklist of new country file (ticket #2759) 2020-09-16 13:43:14 +00:00
zzz
aa07775a32 Blocklist: Move HTML status generation to console 2020-09-11 17:21:04 +00:00
zzz
30244f9d9b Router: Use MuxedSKM for ECIES routers (proposal 156 WIP) 2020-09-11 14:13:36 +00:00
zzz
19d4a5ce26 Blocklist: Refactoring (ticket #2759 WIP) 2020-09-10 16:20:08 +00:00
zzz
e4cb730c1b GeoIP: Generate country blocklist when hidden (ticket #2759)
WIP - full blocking requires restart for now
2020-09-10 14:00:04 +00:00
zzz
3b18e54545 Console: Fix /configclients help message for split client config files 2020-09-10 13:01:18 +00:00
zzz
2fbbd8e7d1 Crypto: Cache HMAC256 instances
Appx. 38% speedup
As suggested by jogger
2020-09-09 21:13:37 +00:00
zzz
e466331407 GeoIP: Add methods to get all IPs for a country
from a geoip 1 or 2 database,
to prep for a country blocklist (ticket #2759)
WIP - not hooked in yet
2020-09-09 15:26:24 +00:00
zzz
5d1f46e6c4 Blocklist: Track versions of each file
Adjust synchronization
Fix logging for feed file
Prep for a country blocklist (ticket #2759 WIP)
2020-09-08 13:38:10 +00:00
zzz
36318def69 Tunnels: BuildRequestor minor cleanup 2020-09-08 13:32:24 +00:00
zzz
72e4b16c1a I2NP BRR: Minor cleanup and javadoc note 2020-09-08 13:26:33 +00:00
zzz
8a10c3a097 NTCP: Call afterSend() for multiple messages in NTCP2 (ticket #2769) 2020-09-08 13:17:46 +00:00
zzz
d402300dba Console: Support remote lookup of full router hash from search form 2020-09-04 16:57:40 +00:00
zzz
ada6753255 Tunnels: For now, don't try to decrypt a build record with a ECIES key (proposal 152 WIP) 2020-09-04 15:03:14 +00:00
zzz
ceb0749e0d Util: Fix decompression of compressed zero bytes (ticket #2770) 2020-09-02 15:57:04 +00:00
zzz
4863ab3711 javadoc 2020-09-02 13:51:27 +00:00
zzz
c745cc8aa1 Ratchet: Change SparseArray from int to char to reduce space 2020-09-02 13:48:30 +00:00
zzz
273902f616 SSU: Randomize intro key 2020-09-02 13:26:10 +00:00
zzz
bb761aea96 Router: Prep for router encryption types (Proposal 156 WIP) 2020-09-02 13:09:38 +00:00
zzz
d13a7d2872 Router: Reduce next key threshold for ratchet 2020-09-02 12:55:21 +00:00
zzz
49b2ca061c New Ed25519 destinations for postman's servers 2020-09-02 12:52:25 +00:00
hankhill19580
3e23ec8d27 fix trac#2768 2020-09-01 14:14:39 +00:00
zzz
22eeb90b81 Bump -1 2020-08-29 13:44:11 +00:00
zzz
6a69cef2a8 Ratchet: Minor cleanup 2020-08-29 13:41:48 +00:00
zzz
c1fef302f3 Crypto: ChaCha small initialization speedup 2020-08-29 13:39:52 +00:00
zzz
bd370cf407 spelling fix 2020-08-29 13:34:42 +00:00
zzz
feba993019 javadoc fix 2020-08-29 13:34:00 +00:00
zzz
623a11dd8f console: ngettext fixes 2020-08-29 13:32:34 +00:00
zzz
ba7fb00450 i2ptunnel: Prevent changing alt private key file while running 2020-08-29 12:52:00 +00:00
zzz
20b4186331 merge of '554c9e737b3a7b6585cc36c8e22de6012ca57754'
and 'cd8c225752a1e1e5be98c13e7e7f5fdb2b160642'
2020-08-25 19:50:03 +00:00
zzz
2479645d22 Debian files and checklists update for 0.9.47 2020-08-25 19:49:54 +00:00
hankhill19580
8585e2e955 fix heading alignment for console news on light theme 2020-08-24 17:20:34 +00:00
hankhill19580
14518dc396 fix missing classic icons from imagegen css/index, removed classic reference ie-compatability from css.jsi 2020-08-24 17:15:40 +00:00
idk
1154d28be7 add a bundle target to ant that generates a current git bundle and corresponding torrent. 2020-03-18 13:39:22 -04:00
1432 changed files with 81289 additions and 65156 deletions

31
.dockerignore Normal file
View File

@@ -0,0 +1,31 @@
.idea
.git
Dockerfile
# Gradle
.gradle
build
apps/BOB/build
apps/addressbook/build
apps/desktopgui/build
apps/i2pcontrol/build
apps/i2psnark/build
apps/i2ptunnel/build
apps/imagegen/build
apps/jetty/build
apps/jrobin/build
apps/ministreaming/java/build
apps/ministreaming/build
apps/routerconsole/build
apps/sam/build
apps/streaming/build
apps/susidns/build
apps/susimail/build
apps/systray/build
core/java/build
core/build
installer/build
router/java/build
router/build

6
.gitignore vendored
View File

@@ -54,4 +54,10 @@ sloccount.sc
.settings/
# IDEA
*.iml
.idea
# Gradle
.gradle
# TODO: why does this file appear?
apps/routerconsole/jsp/favicon.ico

66
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,66 @@
image: openjdk:8-alpine
stages:
- test
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
- .gradle
test:
stage: test
coverage: '/Total.*?([0-9]{1,3})%/'
before_script:
- apk add --no-cache grep
script:
- ./gradlew codeCoverageReport
# The actual output that will be parsed by the code coverage
- grep -oP "Total.*?%" build/reports/jacoco/html/index.html
only:
- merge_requests
- tags
# Make sure we can build a docker image
# It's cached for later jobs
build_docker:
stage: test
image: docker:19.03.12
services:
- docker:19.03.12-dind
script:
# Try to load latest branch image from local tar or from registry
- docker load -i ci-exports/$CI_COMMIT_REF_SLUG.tar || docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:latest .
- mkdir -p ci-exports/
- docker save $CI_REGISTRY_IMAGE:latest > ci-exports/$CI_COMMIT_REF_SLUG.tar
variables:
# When using dind service, we need to instruct docker to talk with
# the daemon started inside of the service. The daemon is available
# with a network connection instead of the default
# /var/run/docker.sock socket. Docker 19.03 does this automatically
# by setting the DOCKER_HOST in
# https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29
#
# The 'docker' hostname is the alias of the service container as described at
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
#
# Specify to Docker where to create the certificates, Docker will
# create them automatically on boot, and will create
# `/certs/client` that will be shared between the service and job
# container, thanks to volume mount from config.toml
DOCKER_TLS_CERTDIR: "/certs"
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
cache:
# The same key should be used across branches
key: "$CI_COMMIT_REF_SLUG"
paths:
- ci-exports/*.tar
only:
- master
- merge_requests
- tags

6
.idea/ant.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/build.xml" />
</component>
</project>

41
.idea/compiler.xml generated
View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel>
<module name="addressbook_main" target="1.7" />
<module name="addressbook_test" target="1.7" />
<module name="BOB_main" target="1.7" />
<module name="BOB_test" target="1.7" />
<module name="core_main" target="1.7" />
<module name="core_test" target="1.7" />
<module name="desktopgui_main" target="1.7" />
<module name="desktopgui_test" target="1.7" />
<module name="i2psnark_main" target="1.7" />
<module name="i2psnark_test" target="1.7" />
<module name="i2ptunnel_main" target="1.7" />
<module name="i2ptunnel_test" target="1.7" />
<module name="installer_main" target="1.7" />
<module name="installer_test" target="1.7" />
<module name="jetty_main" target="1.7" />
<module name="jetty_test" target="1.7" />
<module name="jrobin_main" target="1.7" />
<module name="jrobin_test" target="1.7" />
<module name="ministreaming_main" target="1.7" />
<module name="ministreaming_test" target="1.7" />
<module name="router_main" target="1.7" />
<module name="router_test" target="1.7" />
<module name="routerconsole_main" target="1.7" />
<module name="routerconsole_test" target="1.7" />
<module name="sam_main" target="1.7" />
<module name="sam_test" target="1.7" />
<module name="streaming_main" target="1.7" />
<module name="streaming_test" target="1.7" />
<module name="susidns_main" target="1.7" />
<module name="susidns_test" target="1.7" />
<module name="susimail_main" target="1.7" />
<module name="susimail_test" target="1.7" />
<module name="systray_main" target="1.7" />
<module name="systray_test" target="1.7" />
</bytecodeTargetLevel>
</component>
</project>

View File

@@ -1,3 +0,0 @@
<component name="CopyrightManager">
<settings default="" />
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="javax.servlet.jsp-2.2.0.v201112011158">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jsp/javax.servlet.jsp-2.2.0.v201112011158.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,22 +0,0 @@
<component name="libraryTable">
<library name="jettylib">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-security-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-servlets-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-deploy-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-util-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-servlet-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-http-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-xml-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-server-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/servlet-api-3.0.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-jmx-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-webapp-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-io-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-continuation-8.1.17.v20150415.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/lib/jetty-rewrite-8.1.17.v20150415.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="jrobin-1.5.9.1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/jrobin/jrobin-1.5.9.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,10 +0,0 @@
<component name="libraryTable">
<library name="lib">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/susidns/src/lib/jstl.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/susidns/src/lib/standard.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="start">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/jetty/jetty-distribution-8.1.17.v20150415/start.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="systray4j">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/systray/java/lib/systray4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="tomcat-coyote-util">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat/lib/tomcat-coyote-util.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,12 +0,0 @@
<component name="libraryTable">
<library name="tomcat-lib">
<CLASSES>
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/tomcat-juli.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/el-api.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/jasper.jar!/" />
<root url="jar://$PROJECT_DIR$/apps/jetty/apache-tomcat-deployer/lib/jasper-el.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="wrapper">
<CLASSES>
<root url="jar://$PROJECT_DIR$/installer/lib/wrapper/all/wrapper.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="wrapper-win">
<CLASSES>
<root url="jar://$PROJECT_DIR$/installer/lib/wrapper/win-all/wrapper.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

57
.idea/misc.xml generated
View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ClientPropertiesManager">
<properties class="javax.swing.AbstractButton">
<property name="hideActionText" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JComponent">
<property name="html.disable" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JEditorPane">
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
<property name="charset" class="java.lang.String" />
</properties>
<properties class="javax.swing.JList">
<property name="List.isFileList" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JPasswordField">
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JSlider">
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
<property name="JSlider.isFilled" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JTable">
<property name="Table.isFileList" class="java.lang.Boolean" />
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JToolBar">
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JTree">
<property name="JTree.lineStyle" class="java.lang.String" />
</properties>
<properties class="javax.swing.text.JTextComponent">
<property name="caretAspectRatio" class="java.lang.Double" />
<property name="caretWidth" class="java.lang.Integer" />
</properties>
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build" />
</component>
</project>

80
.idea/modules.xml generated
View File

@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/BOB/BOB.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/BOB/BOB.iml" group="apps/BOB" />
<module fileurl="file://$PROJECT_DIR$/apps/BOB/BOB.iml" filepath="$PROJECT_DIR$/apps/BOB/BOB.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/BOB/BOB_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/BOB/BOB_main.iml" group="apps/BOB" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/BOB/BOB_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/BOB/BOB_test.iml" group="apps/BOB" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/addressbook/addressbook.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/addressbook/addressbook.iml" group="apps/addressbook" />
<module fileurl="file://$PROJECT_DIR$/apps/addressbook/addressbook.iml" filepath="$PROJECT_DIR$/apps/addressbook/addressbook.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/addressbook/addressbook_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/addressbook/addressbook_main.iml" group="apps/addressbook" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/addressbook/addressbook_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/addressbook/addressbook_test.iml" group="apps/addressbook" />
<module fileurl="file://$PROJECT_DIR$/apps/admin/admin.iml" filepath="$PROJECT_DIR$/apps/admin/admin.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/apps.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/apps.iml" group="apps" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/core/core.iml" filepath="$PROJECT_DIR$/.idea/modules/core/core.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/core/core.iml" filepath="$PROJECT_DIR$/core/core.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/core/core_main.iml" filepath="$PROJECT_DIR$/.idea/modules/core/core_main.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/core/core_test.iml" filepath="$PROJECT_DIR$/.idea/modules/core/core_test.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/desktopgui/desktopgui.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/desktopgui/desktopgui.iml" group="apps/desktopgui" />
<module fileurl="file://$PROJECT_DIR$/apps/desktopgui/desktopgui.iml" filepath="$PROJECT_DIR$/apps/desktopgui/desktopgui.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/desktopgui/desktopgui_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/desktopgui/desktopgui_main.iml" group="apps/desktopgui" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/desktopgui/desktopgui_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/desktopgui/desktopgui_test.iml" group="apps/desktopgui" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/i2p.i2p.sl.iml" filepath="$PROJECT_DIR$/.idea/modules/i2p.i2p.sl.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/i2psnark/i2psnark.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/i2psnark/i2psnark.iml" group="apps/i2psnark" />
<module fileurl="file://$PROJECT_DIR$/apps/i2psnark/i2psnark.iml" filepath="$PROJECT_DIR$/apps/i2psnark/i2psnark.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/i2psnark/i2psnark_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/i2psnark/i2psnark_main.iml" group="apps/i2psnark" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/i2psnark/i2psnark_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/i2psnark/i2psnark_test.iml" group="apps/i2psnark" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/i2ptunnel/i2ptunnel.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/i2ptunnel/i2ptunnel.iml" group="apps/i2ptunnel" />
<module fileurl="file://$PROJECT_DIR$/apps/i2ptunnel/i2ptunnel.iml" filepath="$PROJECT_DIR$/apps/i2ptunnel/i2ptunnel.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/i2ptunnel/i2ptunnel_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/i2ptunnel/i2ptunnel_main.iml" group="apps/i2ptunnel" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/i2ptunnel/i2ptunnel_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/i2ptunnel/i2ptunnel_test.iml" group="apps/i2ptunnel" />
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/identicon/identicon.iml" filepath="$PROJECT_DIR$/apps/imagegen/identicon/identicon.iml" />
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/imagegen/imagegen.iml" filepath="$PROJECT_DIR$/apps/imagegen/imagegen/imagegen.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/installer/installer.iml" filepath="$PROJECT_DIR$/.idea/modules/installer/installer.iml" group="installer" />
<module fileurl="file://$PROJECT_DIR$/installer/installer.iml" filepath="$PROJECT_DIR$/installer/installer.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/installer/installer_main.iml" filepath="$PROJECT_DIR$/.idea/modules/installer/installer_main.iml" group="installer" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/installer/installer_test.iml" filepath="$PROJECT_DIR$/.idea/modules/installer/installer_test.iml" group="installer" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/jetty/jetty.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/jetty/jetty.iml" group="apps/jetty" />
<module fileurl="file://$PROJECT_DIR$/apps/jetty/jetty.iml" filepath="$PROJECT_DIR$/apps/jetty/jetty.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/jetty/jetty_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/jetty/jetty_main.iml" group="apps/jetty" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/jetty/jetty_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/jetty/jetty_test.iml" group="apps/jetty" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/jrobin/jrobin.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/jrobin/jrobin.iml" group="apps/jrobin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/jrobin/jrobin_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/jrobin/jrobin_main.iml" group="apps/jrobin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/jrobin/jrobin_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/jrobin/jrobin_test.iml" group="apps/jrobin" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/ministreaming/ministreaming.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/ministreaming/ministreaming.iml" group="apps/ministreaming" />
<module fileurl="file://$PROJECT_DIR$/apps/ministreaming/ministreaming.iml" filepath="$PROJECT_DIR$/apps/ministreaming/ministreaming.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/ministreaming/ministreaming_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/ministreaming/ministreaming_main.iml" group="apps/ministreaming" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/ministreaming/ministreaming_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/ministreaming/ministreaming_test.iml" group="apps/ministreaming" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/router/router.iml" filepath="$PROJECT_DIR$/.idea/modules/router/router.iml" group="router" />
<module fileurl="file://$PROJECT_DIR$/router/router.iml" filepath="$PROJECT_DIR$/router/router.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/router/router_main.iml" filepath="$PROJECT_DIR$/.idea/modules/router/router_main.iml" group="router" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/router/router_test.iml" filepath="$PROJECT_DIR$/.idea/modules/router/router_test.iml" group="router" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/routerconsole/routerconsole.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/routerconsole/routerconsole.iml" group="apps/routerconsole" />
<module fileurl="file://$PROJECT_DIR$/apps/routerconsole/routerconsole.iml" filepath="$PROJECT_DIR$/apps/routerconsole/routerconsole.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/routerconsole/routerconsole_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/routerconsole/routerconsole_main.iml" group="apps/routerconsole" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/routerconsole/routerconsole_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/routerconsole/routerconsole_test.iml" group="apps/routerconsole" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/sam/sam.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/sam/sam.iml" group="apps/sam" />
<module fileurl="file://$PROJECT_DIR$/apps/sam/sam.iml" filepath="$PROJECT_DIR$/apps/sam/sam.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/sam/sam_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/sam/sam_main.iml" group="apps/sam" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/sam/sam_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/sam/sam_test.iml" group="apps/sam" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/streaming/streaming.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/streaming/streaming.iml" group="apps/streaming" />
<module fileurl="file://$PROJECT_DIR$/apps/streaming/streaming.iml" filepath="$PROJECT_DIR$/apps/streaming/streaming.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/streaming/streaming_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/streaming/streaming_main.iml" group="apps/streaming" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/streaming/streaming_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/streaming/streaming_test.iml" group="apps/streaming" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/susidns/susidns.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/susidns/susidns.iml" group="apps/susidns" />
<module fileurl="file://$PROJECT_DIR$/apps/susidns/susidns.iml" filepath="$PROJECT_DIR$/apps/susidns/susidns.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/susidns/susidns_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/susidns/susidns_main.iml" group="apps/susidns" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/susidns/susidns_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/susidns/susidns_test.iml" group="apps/susidns" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/susimail/susimail.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/susimail/susimail.iml" group="apps/susimail" />
<module fileurl="file://$PROJECT_DIR$/apps/susimail/susimail.iml" filepath="$PROJECT_DIR$/apps/susimail/susimail.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/susimail/susimail_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/susimail/susimail_main.iml" group="apps/susimail" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/susimail/susimail_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/susimail/susimail_test.iml" group="apps/susimail" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/systray/systray.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/systray/systray.iml" group="apps/systray" />
<module fileurl="file://$PROJECT_DIR$/apps/systray/systray.iml" filepath="$PROJECT_DIR$/apps/systray/systray.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/systray/systray_main.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/systray/systray_main.iml" group="apps/systray" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/apps/systray/systray_test.iml" filepath="$PROJECT_DIR$/.idea/modules/apps/systray/systray_test.iml" group="apps/systray" />
<module fileurl="file://$PROJECT_DIR$/apps/imagegen/zxing/zxing.iml" filepath="$PROJECT_DIR$/apps/imagegen/zxing/zxing.iml" />
</modules>
</component>
</project>

View File

@@ -1,6 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="updater" type="AntRunConfiguration" factoryName="Ant Target">
<antsettings antfile="file://$PROJECT_DIR$/build.xml" target="updater" />
<method />
</configuration>
</component>

View File

@@ -1,17 +1,17 @@
language: java
dist: xenial
dist: bionic
jdk:
- oraclejdk11
matrix:
include:
- jdk: oraclejdk8
- jdk: oraclejdk11
addons:
sonarcloud:
organization: "i2p"
before_install:
- sed -i "1iplugins {\n id 'org.sonarqube' version '2.6.1'\n}\n" build.gradle
- sed -i "1iplugins {\n id 'org.sonarqube' version '3.0'\n}\n" build.gradle
- jdk: openjdk8
before_cache:
@@ -24,13 +24,11 @@ cache:
- $HOME/.sonar/cache/
- .gradle
env:
- SONAR_SCANNER_OPTS="-Xmx2048m"
script:
- |
if [ "$TRAVIS_JDK_VERSION" == "oraclejdk8" ]; then
./gradlew sonarqube codeCoverageReport
else
./gradlew check codeCoverageReport
fi
- travis_wait 45 ./tests/scripts/travis.sh
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@@ -87,6 +87,7 @@ trans.id = core/locale/messages_in.po
trans.it = core/locale/messages_it.po
trans.ja = core/locale/messages_ja.po
trans.ko = core/locale/messages_ko.po
trans.ku = core/locale/messages_ku.po
trans.nb = core/locale/messages_nb.po
trans.nl = core/locale/messages_nl.po
trans.pl = core/locale/messages_pl.po
@@ -95,6 +96,7 @@ trans.pt_BR = core/locale/messages_pt_BR.po
trans.ro = core/locale/messages_ro.po
trans.ru_RU = core/locale/messages_ru.po
trans.sv_SE = core/locale/messages_sv.po
trans.tk = core/locale/messages_tk.po
trans.tr_TR = core/locale/messages_tr.po
trans.uk_UA = core/locale/messages_uk.po
trans.vi = core/locale/messages_vi.po
@@ -122,6 +124,7 @@ trans.id = router/locale/messages_in.po
trans.it = router/locale/messages_it.po
trans.ja = router/locale/messages_ja.po
trans.ko = router/locale/messages_ko.po
trans.ku = router/locale/messages_ku.po
trans.nb = router/locale/messages_nb.po
trans.nl = router/locale/messages_nl.po
trans.pl = router/locale/messages_pl.po
@@ -130,6 +133,7 @@ trans.pt_BR = router/locale/messages_pt_BR.po
trans.ro = router/locale/messages_ro.po
trans.ru_RU = router/locale/messages_ru.po
trans.sv_SE = router/locale/messages_sv.po
trans.tk = router/locale/messages_tk.po
trans.tr_TR = router/locale/messages_tr.po
trans.uk_UA = router/locale/messages_uk.po
trans.vi = router/locale/messages_vi.po
@@ -190,6 +194,7 @@ trans.id = apps/routerconsole/locale-news/messages_in.po
trans.it = apps/routerconsole/locale-news/messages_it.po
trans.ja = apps/routerconsole/locale-news/messages_ja.po
trans.ko = apps/routerconsole/locale-news/messages_ko.po
trans.ku = apps/routerconsole/locale-news/messages_ku.po
trans.mg = apps/routerconsole/locale-news/messages_mg.po
trans.nb = apps/routerconsole/locale-news/messages_nb.po
trans.nl = apps/routerconsole/locale-news/messages_nl.po
@@ -202,6 +207,7 @@ trans.sk = apps/routerconsole/locale-news/messages_sk.po
trans.sq = apps/routerconsole/locale-news/messages_sq.po
trans.sr = apps/routerconsole/locale-news/messages_sr.po
trans.sv_SE = apps/routerconsole/locale-news/messages_sv.po
trans.tk = apps/routerconsole/locale-news/messages_tk.po
trans.tr_TR = apps/routerconsole/locale-news/messages_tr.po
trans.uk_UA = apps/routerconsole/locale-news/messages_uk.po
trans.zh_CN = apps/routerconsole/locale-news/messages_zh.po
@@ -235,6 +241,7 @@ trans.id = apps/routerconsole/locale-countries/messages_in.po
trans.it = apps/routerconsole/locale-countries/messages_it.po
trans.ja = apps/routerconsole/locale-countries/messages_ja.po
trans.ko = apps/routerconsole/locale-countries/messages_ko.po
trans.ku = apps/routerconsole/locale-countries/messages_ku.po
trans.mg = apps/routerconsole/locale-countries/messages_mg.po
trans.nb = apps/routerconsole/locale-countries/messages_nb.po
trans.nl = apps/routerconsole/locale-countries/messages_nl.po
@@ -247,6 +254,7 @@ trans.sk = apps/routerconsole/locale-countries/messages_sk.po
trans.sq = apps/routerconsole/locale-countries/messages_sq.po
trans.sr = apps/routerconsole/locale-countries/messages_sr.po
trans.sv_SE = apps/routerconsole/locale-countries/messages_sv.po
trans.tk = apps/routerconsole/locale-countries/messages_tk.po
trans.tr_TR = apps/routerconsole/locale-countries/messages_tr.po
trans.uk_UA = apps/routerconsole/locale-countries/messages_uk.po
trans.vi = apps/routerconsole/locale-countries/messages_vi.po
@@ -330,6 +338,7 @@ trans.da = apps/desktopgui/locale/messages_da.po
trans.de = apps/desktopgui/locale/messages_de.po
trans.el = apps/desktopgui/locale/messages_el.po
trans.es = apps/desktopgui/locale/messages_es.po
trans.es_AR = apps/desktopgui/locale/messages_es_AR.po
trans.fa = apps/desktopgui/locale/messages_fa.po
trans.fi = apps/desktopgui/locale/messages_fi.po
trans.fr = apps/desktopgui/locale/messages_fr.po
@@ -340,6 +349,7 @@ trans.id = apps/desktopgui/locale/messages_in.po
trans.it = apps/desktopgui/locale/messages_it.po
trans.ja = apps/desktopgui/locale/messages_ja.po
trans.ko = apps/desktopgui/locale/messages_ko.po
trans.ku = apps/desktopgui/locale/messages_ku.po
trans.mg = apps/desktopgui/locale/messages_mg.po
trans.nb = apps/desktopgui/locale/messages_nb.po
trans.nl = apps/desktopgui/locale/messages_nl.po
@@ -353,6 +363,7 @@ trans.sr = apps/desktopgui/locale/messages_sr.po
trans.sv_SE = apps/desktopgui/locale/messages_sv.po
trans.sq = apps/desktopgui/locale/messages_sq.po
trans.uk_UA = apps/desktopgui/locale/messages_uk.po
trans.tk = apps/desktopgui/locale/messages_tk.po
trans.tr_TR = apps/desktopgui/locale/messages_tr.po
trans.vi = apps/desktopgui/locale/messages_vi.po
trans.zh_CN = apps/desktopgui/locale/messages_zh.po
@@ -428,6 +439,7 @@ trans.ru_RU = debian/po/ru.po
trans.sk = debian/po/sk.po
trans.sq = debian/po/sq.po
trans.sv_SE = debian/po/sv.po
trans.tk = debian/po/tk.po
trans.tr_TR = debian/po/tr.po
trans.uk_UA = debian/po/uk.po
trans.zh_CN = debian/po/zh.po
@@ -494,6 +506,7 @@ trans.id = core/java/src/gnu/getopt/MessagesBundle_in.properties
trans.it = core/java/src/gnu/getopt/MessagesBundle_it.properties
trans.ja = core/java/src/gnu/getopt/MessagesBundle_ja.properties
trans.ko = core/java/src/gnu/getopt/MessagesBundle_ko.properties
trans.ku = core/java/src/gnu/getopt/MessagesBundle_ku.properties
trans.nb = core/java/src/gnu/getopt/MessagesBundle_nb.properties
trans.nl = core/java/src/gnu/getopt/MessagesBundle_nl.properties
trans.pl = core/java/src/gnu/getopt/MessagesBundle_pl.properties
@@ -536,6 +549,7 @@ trans.pt_BR = apps/ministreaming/locale/messages_pt_BR.po
trans.ro = apps/ministreaming/locale/messages_ro.po
trans.ru_RU = apps/ministreaming/locale/messages_ru.po
trans.sv_SE = apps/ministreaming/locale/messages_sv.po
trans.tk = apps/ministreaming/locale/messages_tk.po
trans.tr_TR = apps/ministreaming/locale/messages_tr.po
trans.uk_UA = apps/ministreaming/locale/messages_uk.po
trans.zh_CN = apps/ministreaming/locale/messages_zh.po
@@ -605,21 +619,21 @@ trans.tr_TR = installer/resources/eepsite/docroot/help/index_tr.html
;; Text on /console
;;
type = HTML
source_file = installer/resources/readme/readme.html
source_file = apps/routerconsole/resources/docs/readme.html
source_lang = en
trans.ar = installer/resources/readme/readme_ar.html
trans.de = installer/resources/readme/readme_de.html
trans.fr = installer/resources/readme/readme_fr.html
trans.ar = apps/routerconsole/resources/docs/readme_ar.html
trans.de = apps/routerconsole/resources/docs/readme_de.html
trans.fr = apps/routerconsole/resources/docs/readme_fr.html
;; Java converts id to in
trans.id = installer/resources/readme/readme_in.html
trans.it = installer/resources/readme/readme_it.html
trans.ja = installer/resources/readme/readme_ja.html
trans.pl = installer/resources/readme/readme_pl.html
trans.pt = installer/resources/readme/readme_pt.html
trans.ro = installer/resources/readme/readme_ro.html
trans.ru_RU = installer/resources/readme/readme_ru.html
trans.tr_TR = installer/resources/readme/readme_tr.html
trans.zh_CN = installer/resources/readme/readme_zh.html
trans.id = apps/routerconsole/resources/docs/readme_in.html
trans.it = apps/routerconsole/resources/docs/readme_it.html
trans.ja = apps/routerconsole/resources/docs/readme_ja.html
trans.pl = apps/routerconsole/resources/docs/readme_pl.html
trans.pt = apps/routerconsole/resources/docs/readme_pt.html
trans.ro = apps/routerconsole/resources/docs/readme_ro.html
trans.ru_RU = apps/routerconsole/resources/docs/readme_ru.html
trans.tr_TR = apps/routerconsole/resources/docs/readme_tr.html
trans.zh_CN = apps/routerconsole/resources/docs/readme_zh.html
[main]
host = https://www.transifex.com

View File

@@ -1,14 +0,0 @@
#!/bin/sh
export JAVA_HOME=/opt/jdk/jre
# Ensure user rights
chown -R i2p:nobody /opt/i2p
chmod -R u+rwx /opt/i2p
gosu i2p /opt/i2p/i2psvc /opt/i2p/wrapper.config wrapper.pidfile=/var/tmp/i2p.pid \
wrapper.name=i2p \
wrapper.displayname="I2P Service" \
wrapper.statusfile=/var/tmp/i2p.status \
wrapper.java.statusfile=/var/tmp/i2p.java.status \
wrapper.logfile=/var/tmp/wrapper.log

View File

@@ -1,62 +1,40 @@
FROM meeh/java8server:latest
# Docker image based on Alpine with Java.
# Use a multi-stage build to reduce the size of the resulting image
# We need alpine >v3 in order to install an apache-ant > 1.9
FROM debian:buster-slim as builder
# We use Oracle Java to run I2P, but uses the openjdk to build it.
ENV DEBIAN_FRONTEND=noninteractive
# Build installer
RUN apt-get update \
# Workaround for installing openjdk-11-jre-headless
&& mkdir -p /usr/share/man/man1 \
&& apt-get -qqqy install debhelper ant debconf gettext libgmp-dev po-debconf fakeroot \
build-essential quilt dh-apparmor dh-systemd libservice-wrapper-java libjson-simple-java \
devscripts libjetty9-java libtomcat9-java libtaglibs-standard-jstlel-java libgetopt-java \
bash-completion
MAINTAINER Mikal Villa <mikal@sigterm.no>
WORKDIR /tmp/build
COPY . ./
ENV GIT_BRANCH="master"
ENV I2P_PREFIX="/opt/i2p"
ENV PATH=${I2P_PREFIX}/bin:$PATH
ENV JAVA_HOME=/usr/lib/jvm/default-jvm
RUN ant debian
ENV GOSU_VERSION=1.7
ENV GOSU_SHASUM="34049cfc713e8b74b90d6de49690fa601dc040021980812b2f1f691534be8a50 /usr/local/bin/gosu"
RUN mkdir /user && adduser -S -h /user i2p && chown -R i2p:nobody /user
# Adding files first, since Docker.expt is required for installation
ADD Docker.expt /tmp/Docker.expt
ADD Docker.entrypoint.sh /entrypoint.sh
# Required for wget https
RUN apk add --no-cache openssl
# Gosu is a replacement for su/sudo in docker and not a backdoor :) See https://github.com/tianon/gosu
RUN wget -O /usr/local/bin/gosu https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-amd64 \
&& echo "${GOSU_SHASUM}" | sha256sum -c && chmod +x /usr/local/bin/gosu
#
# Each RUN is a layer, adding the dependencies and building i2pd in one layer takes around 8-900Mb, so to keep the
# image under 200mb we need to remove all the build dependencies in the same "RUN" / layer.
#
# The main layer
RUN apk --no-cache add build-base git gettext tar bzip2 apache-ant openjdk8 expect \
&& mkdir -p /usr/src/build \
&& cd /usr/src/build \
&& git clone -b ${GIT_BRANCH} https://github.com/i2p/i2p.i2p.git \
&& cd /usr/src/build/i2p.i2p \
&& echo "noExe=true" >> build.properties \
&& ant installer-linux \
&& cp i2pinstall*.jar /tmp/i2pinstall.jar \
&& mkdir -p /opt \
&& chown i2p:root /opt \
&& chmod u+rw /opt \
&& gosu i2p expect -f /tmp/Docker.expt \
&& cd ${I2P_PREFIX} \
&& rm -fr man docs *.bat *.command *.app /tmp/i2pinstall.jar /tmp/Docker.expt \
&& rm -fr /usr/src/build \
&& apk --purge del build-base apache-ant expect tcl expat git openjdk8 openjdk8-jre openjdk8-jre-base openjdk8-jre-lib bzip2 tar \
binutils-libs binutils pkgconfig libcurl libc-dev musl-dev g++ make fortify-headers pkgconf giflib libssh2 libxdmcp libxcb \
libx11 pcre alsa-lib libxi libxrender libxml2 readline bash openssl \
&& rm -fr /usr/lib/jvm/default-jre \
&& ln -sf /opt/jdk/jre /usr/lib/jvm/default-jre \
&& chmod a+x /entrypoint.sh
# Second stage only using the installer from the last stage
# ---------------------------------------------------------
# We can't use alpine here as the java service wrapper is built with glibc
# alpine uses musl
FROM openjdk:11.0-jre-slim
# "install" i2p by copying over installed files
COPY --from=builder /tmp/*.deb /tmp/
# Install and configure
RUN apt-get update -qqq \
&& apt-get -qqqy install geoip-database famfamfam-flag-png \
&& dpkb -i /tmp/*
EXPOSE 7654 7656 7657 7658 4444 6668 8998 7659 7660 4445 15000-20000
ENTRYPOINT [ "/entrypoint.sh" ]
USER i2psvc
ENTRYPOINT [ "/usr/bin/i2prouter" ]
CMD start

View File

@@ -1,10 +1,10 @@
I2P source installation instructions
Prerequisites to build from source:
Java SDK (preferably Oracle/Sun or OpenJDK) 1.8.0 or higher
Java SDK (preferably Oracle or OpenJDK) 8 or higher
Non-linux operating systems and JVMs: See https://trac.i2p2.de/wiki/java
Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel) require only Java 1.6
Apache Ant 1.7.0 or higher
Apache Ant 1.9.8 or higher
The xgettext, msgfmt, and msgmerge tools installed
from the GNU gettext package http://www.gnu.org/software/gettext/
Build environment must use a UTF-8 locale.

View File

@@ -36,10 +36,6 @@ Public domain except as listed below:
Copyright (c) 2003, TheCrypto
See licenses/LICENSE-ElGamalDSA.txt
HMAC:
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
See licenses/LICENSE-SHA256.txt
ElGamal:
Copyright (c) 2000 - 2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
See licenses/LICENSE-SHA256.txt
@@ -98,6 +94,12 @@ Public domain except as listed below:
Copyright (C) 2016 Southern Storm Software, Pty Ltd.
See licenses/LICENSE-Noise.txt
MiniDNS library 1.0.0
This software may be used under the terms of (at your choice)
- LGPL version 2 (or later) (see licenses/LICENSE-LGPL2.1.txt)
- Apache Software licence (see licenses/LICENSE-Apache2.0.txt)
- DWTFYWTPL
Router (router.jar):
Public domain except as listed below:
@@ -126,6 +128,10 @@ Public domain except as listed below:
Copyright (C) 2006 The Android Open Source Project
See licenses/LICENSE-Apache2.0.txt
SSU HMAC:
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
See licenses/LICENSE-SHA256.txt
Installer:
(not included in distribution packages)
@@ -180,10 +186,10 @@ Launchers:
Copyright (c) 2002-2018 EPFL, Lausanne / Lightbend, Inc. , unless otherwise specified.
See licenses/LICENSE-Scala.md
Java Service Wrapper Community Edition 3.5.39:
Java Service Wrapper Community Edition 3.5.44:
(Windows: 3.5.25)
(not included in most distribution packages)
Copyright (C) 1999-2019 Tanuki Software, Ltd. All Rights Reserved.
Copyright (C) 1999-2020 Tanuki Software, Ltd. All Rights Reserved.
See licenses/LICENSE-Wrapper.txt
@@ -193,7 +199,7 @@ Jbigi Libraries (jbigi.jar):
GMP 4.3.2 / 5.0.2:
Copyright 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc.
See licenses/LICENSE-LGPLv3.txt
GMP 6.0.0 / 6.1.2:
GMP 6.0.0 / 6.1.2 / 6.2.0:
See licenses/LICENSE-GPLv2.txt
@@ -255,10 +261,10 @@ Applications:
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
Copyright (c) 2008 Alexander von Gernler. All rights reserved.
See licenses/LICENSE-BSD.txt
Zxing 3.3.0:
Zxing 3.4.1:
See licenses/LICENSE-Apache2.0.txt
Jetty 9.3.28.v20191105 (jetty-*.jar, org.mortbay.*.jar):
Jetty 9.3.29.v20201019 (jetty-*.jar, org.mortbay.*.jar):
(not included in most distribution packages, except for jetty-i2p.jar)
See licenses/ABOUT-Jetty.html
See licenses/NOTICE-Jetty.html
@@ -333,7 +339,7 @@ Applications:
Systray (systray.jar):
Public domain.
Tomcat 9.0.35 (jasper-runtime.jar):
Tomcat 9.0.40 (jasper-runtime.jar):
(not included in most distribution packages)
Copyright 1999-2020 The Apache Software Foundation
See licenses/LICENSE-Apache2.0.txt

View File

@@ -27,11 +27,11 @@ To get development branch from source control: [https://geti2p.net/newdevelopers
### Prerequisites
- Java SDK (preferably Oracle/Sun or OpenJDK) 1.8.0 or higher
- Java SDK (preferably Oracle or OpenJDK) 8 or higher
- Non-linux operating systems and JVMs: See [https://trac.i2p2.de/wiki/java](https://trac.i2p2.de/wiki/java)
- Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel)
require only Java 1.6
- Apache Ant 1.7.0 or higher
require only Java 6
- Apache Ant 1.9.8 or higher
- The xgettext, msgfmt, and msgmerge tools installed from the GNU gettext package
[http://www.gnu.org/software/gettext/](http://www.gnu.org/software/gettext/)
- Build environment must use a UTF-8 locale.

View File

@@ -1,8 +1,8 @@
Prerequisites to build from source:
Java SDK (preferably Oracle/Sun or OpenJDK) 1.8.0 or higher
Java SDK (preferably Oracle or OpenJDK) 8 or higher
Non-linux operating systems and JVMs: See https://trac.i2p2.de/wiki/java
Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel) require only Java 1.6
Apache Ant 1.7.0 or higher
Certain subsystems for embedded (core, router, mstreaming, streaming, i2ptunnel) require only Java 6
Apache Ant 1.9.8 or higher
The xgettext, msgfmt, and msgmerge tools installed
from the GNU gettext package http://www.gnu.org/software/gettext/
Build environment must use a UTF-8 locale.

View File

@@ -39,8 +39,9 @@ is divided into following sections:
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
<property name="default.javac.source" value="1.8"/>
<property name="default.javac.target" value="1.8"/>
<property name="javac.release" value="8"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
@@ -155,7 +156,7 @@ is divided into following sections:
<attribute default="/does/not/exist" name="sourcepath"/>
<element name="customize" optional="true"/>
<sequential>
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" release="${javac.release}">
<classpath>
<path path="@{classpath}"/>
</classpath>

View File

@@ -29,28 +29,19 @@ endorsed.classpath=
excludes=**/*.html,**/*.txt
file.reference.build-javadoc=../../i2p.i2p/build/javadoc
file.reference.i2p.jar=../../core/java/build/i2p.jar
file.reference.i2ptunnel.jar=../i2ptunnel/java/build/i2ptunnel.jar
file.reference.jbigi.jar=../../build/jbigi.jar
file.reference.mstreaming.jar=../ministreaming/java/build/mstreaming.jar
file.reference.router.jar=../../router/java/build/router.jar
file.reference.streaming.jar=../streaming/java/build/streaming.jar
file.reference.wrapper.jar=../../installer/lib/wrapper/all/wrapper.jar
includes=**
jar.compress=true
javac.classpath=\
${file.reference.router.jar}:\
${file.reference.i2ptunnel.jar}:\
${file.reference.mstreaming.jar}:\
${file.reference.streaming.jar}:\
${file.reference.wrapper.jar}:\
${file.reference.i2p.jar}:\
${file.reference.router.jar}
${file.reference.i2p.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.version=1.7
javac.version=1.8
javac.source=${javac.version}
javac.target=${javac.version}
javac.release=8
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\

View File

@@ -4,7 +4,7 @@
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>BOB</name>
<minimum-ant-version>1.6.5</minimum-ant-version>
<minimum-ant-version>1.9.8</minimum-ant-version>
<source-roots>
<root id="src.dir"/>
</source-roots>

View File

@@ -38,6 +38,7 @@ import net.i2p.I2PAppContext;
import net.i2p.app.*;
import net.i2p.client.I2PClient;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
import net.i2p.util.SimpleTimer2;
@@ -111,7 +112,9 @@ import net.i2p.util.SimpleTimer2;
* BOB, main command socket listener, launches the command parser engine.
*
* @author sponge
* @deprecated Please port applications to SAMv3
*/
@Deprecated
public class BOB implements Runnable, ClientApp {
public final static String PROP_CONFIG_LOCATION = "BOB.config";
@@ -140,6 +143,7 @@ public class BOB implements Runnable, ClientApp {
private volatile ServerSocket listener;
private volatile Thread _runner;
private volatile boolean _warned;
/**
* Stop BOB gracefully
@@ -342,6 +346,12 @@ public class BOB implements Runnable, ClientApp {
}
if (g) {
if (!_warned) {
_warned = true;
String s = "BOB is deprecated. Please port applications to SAMv3.";
_context.logManager().getLog(BOB.class).logAlways(Log.WARN, s);
_log.warn(s);
}
DoCMDS conn_c = new DoCMDS(spin, lock, server, props, database, _log);
Thread t = new I2PAppThread(conn_c);
t.setName("BOB.DoCMDS " + i);

View File

@@ -1,5 +1,5 @@
<html>
<body>
<p>BOB, the Basic Open Bridge, allows TCP applications to talk over I2P.</p>
<p>BOB, the Basic Open Bridge, allows TCP applications to talk over I2P - DEPRECATED - Please port applications to SAMv3.</p>
</body>
</html>

View File

@@ -8,6 +8,7 @@
<property name="war" value="addressbook.war"/>
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.8" />
<property name="javac.release" value="8" />
<target name="all" depends="jar, emptyWar"/>
@@ -40,6 +41,7 @@
<target name="compile" depends="init, depend, warUpToDate">
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
release="${javac.release}"
includeAntRuntime="false"
encoding="UTF-8"
srcdir="${src}" destdir="${build}">

View File

@@ -77,7 +77,7 @@ class Daemon {
* client applications.
* @param published
* The published AddressBook. This address book is published on
* the user's eepsite so that others may subscribe to it.
* the user's I2P Site so that others may subscribe to it.
* May be null.
* If non-null, overwrite with the new addressbook.
* @param subscriptions
@@ -111,7 +111,7 @@ class Daemon {
* The NamingService to update, generally the root NamingService from the context.
* @param published
* The published AddressBook. This address book is published on
* the user's eepsite so that others may subscribe to it.
* the user's I2P Site so that others may subscribe to it.
* May be null.
* If non-null, overwrite with the new addressbook.
* @param subscriptions

View File

@@ -2069,9 +2069,8 @@ public class BlockfileNamingService extends DummyNamingService {
}
if (baos.size() > 65535)
throw new DataFormatException("Properties too big (65535 max): " + baos.size());
byte propBytes[] = baos.toByteArray();
DataHelper.writeLong(rawStream, 2, propBytes.length);
rawStream.write(propBytes);
DataHelper.writeLong(rawStream, 2, baos.size());
baos.writeTo(rawStream);
} else {
DataHelper.writeLong(rawStream, 2, 0);
}

View File

@@ -2,6 +2,7 @@ sourceSets {
main {
java {
srcDir 'src'
srcDir 'build/messages-src'
}
}
}
@@ -12,3 +13,14 @@ dependencies {
compile project(':installer')
compile project(':apps:systray')
}
// Create the java files from the po files. The jar task will compile them.
// This requires gettext 0.19 or higher.
// We don't support the "slow way"
task bundle {
doLast {
if (!(new File("$buildDir/classes/java/main/net/i2p/desktopgui/messages_de.class")).exists())
println "apps/desktopgui/bundle-messages.sh".execute().text
}
}
jar.dependsOn bundle

View File

@@ -8,6 +8,7 @@
<property name="javadoc" value="javadoc"/>
<property name="javac.compilerargs" value=""/>
<property name="javac.version" value="1.8" />
<property name="javac.release" value="8" />
<property name="require.gettext" value="true" />
<condition property="no.bundle">
@@ -27,6 +28,7 @@
<target name="compile" depends="init">
<javac debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
release="${javac.release}"
includeAntRuntime="false"
encoding="UTF-8"
srcdir="${src}" destdir="${build}">
@@ -52,6 +54,7 @@
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
release="${javac.release}"
includeAntRuntime="false"
encoding="UTF-8"
srcdir="${build}/messages-src" destdir="${build}">
@@ -77,12 +80,14 @@
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<!-- ideal for linux: 24x24, but transparency doesn't work -->
<copy tofile="${build}/desktopgui/resources/images/logo.png" file="../../installer/resources/themes/console/images/itoopie_xsm.png" />
<copy tofile="${build}/desktopgui/resources/images/logo.png" file="../../apps/routerconsole/jsp/themes/console/images/itoopie_xsm.png" />
<copy todir="${build}/desktopgui/resources/images" file="images/itoopie_black_24.png" />
<copy todir="${build}/desktopgui/resources/images" file="images/itoopie_white_24.png" />
<jar basedir="${build}" excludes="messages-src/**" destfile="${dist}/${jar}">
<manifest>
<attribute name="Main-Class" value="net.i2p.desktopgui.Main"/>
<attribute name="Implementation-Version" value="${full.version}" />
<attribute name="Built-By" value="${build.built-by}" />
<attribute name="Build-Date" value="${build.timestamp}" />
<attribute name="Base-Revision" value="${workspace.version}" />
<attribute name="Workspace-Changes" value="${workspace.changes.tr}" />

1
apps/desktopgui/bundle-messages.sh Normal file → Executable file
View File

@@ -11,6 +11,7 @@
# zzz - public domain
# Mathiasdm - modifications for desktopgui
#
cd `dirname $0`
CLASS=net.i2p.desktopgui.messages
TMPFILE=build/javafiles.txt
export TZ=UTC

View File

@@ -0,0 +1,94 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the desktopgui package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# kaze kaze <kaze@rlab.be>, 2017
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2017-11-16 15:29+0000\n"
"Last-Translator: kaze kaze <kaze@rlab.be>\n"
"Language-Team: Spanish (Argentina) (http://www.transifex.com/otf/I2P/language/es_AR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es_AR\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
msgid "Start I2P"
msgstr "Iniciando I2P..."
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "I2P is starting!"
msgstr "I2P esta iniciando!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "Starting"
msgstr "Iniciando"
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "Lanzar el Navegador I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "Configurar la Bandeja de Sistema de I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Deshabilitar"
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "Riniciar I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "Detener I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr " Reiniciar I2P inmediatamente "
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr " Detener I2P inmediatamente "
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "Cancelar el Apagado de I2P"
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "Apagar en {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Apagado inminente"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Red"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P Clic derecho para el menú"

View File

@@ -0,0 +1,94 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the desktopgui package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# Zagros <zagros21@cmail.nu>, 2020
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2020-09-23 21:02+0000\n"
"Last-Translator: Zagros <zagros21@cmail.nu>\n"
"Language-Team: Kurdish (http://www.transifex.com/otf/I2P/language/ku/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ku\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
msgid "Start I2P"
msgstr "I2P بەکاربخە"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "I2P is starting!"
msgstr "وا I2P دەستپێدەکات!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "Starting"
msgstr "دەستپێکردن"
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "وێبگەڕی I2P بکەوە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr ""
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "ناچالاکبکە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "I2P بەکاربخەوە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "I2P بوەستێنە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "دەستبەجێ I2P بەکاربخەوە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "دەستبەجێ I2P بوەستێنە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "کووژاندنەوە I2P هەڵبوەشێنەوە"
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "دەکووژێتەوە لە {0}"
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "دەستبەجێ کووژانەوە"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "ڕایەڵە"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: کرتەی ڕاست بکە بۆ لیستەکان"

View File

@@ -0,0 +1,94 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the desktopgui package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# Alperen Yavuz <mingyu@yaani.com>, 2020
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-05-25 12:29+0000\n"
"PO-Revision-Date: 2020-08-26 20:48+0000\n"
"Last-Translator: Alperen Yavuz <mingyu@yaani.com>\n"
"Language-Team: Turkmen (http://www.transifex.com/otf/I2P/language/tk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: tk\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:31
#: src/net/i2p/desktopgui/ExternalTrayManager.java:59
msgid "Start I2P"
msgstr "I2P başlaň"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "I2P is starting!"
msgstr "I2P başlaýar!"
#: src/net/i2p/desktopgui/ExternalTrayManager.java:44
#: src/net/i2p/desktopgui/ExternalTrayManager.java:72
msgid "Starting"
msgstr "Başlamak"
#: src/net/i2p/desktopgui/InternalTrayManager.java:55
#: src/net/i2p/desktopgui/InternalTrayManager.java:207
msgid "Launch I2P Browser"
msgstr "I2P brauzerini işe giriziň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:76
#: src/net/i2p/desktopgui/InternalTrayManager.java:228
msgid "Configure I2P System Tray"
msgstr "I2P ulgam lýubkasyny sazlaň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:77
#: src/net/i2p/desktopgui/InternalTrayManager.java:229
msgid "Disable"
msgstr "Öçüriň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:93
#: src/net/i2p/desktopgui/InternalTrayManager.java:245
msgid "Restart I2P"
msgstr "I2P-i täzeden açyň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:110
#: src/net/i2p/desktopgui/InternalTrayManager.java:262
msgid "Stop I2P"
msgstr "I2P bes et"
#: src/net/i2p/desktopgui/InternalTrayManager.java:126
#: src/net/i2p/desktopgui/InternalTrayManager.java:278
msgid "Restart I2P Immediately"
msgstr "I2P derrew täzeden açyň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:143
#: src/net/i2p/desktopgui/InternalTrayManager.java:295
msgid "Stop I2P Immediately"
msgstr "Derrew I2P duruzyň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:157
#: src/net/i2p/desktopgui/InternalTrayManager.java:309
msgid "Cancel I2P Shutdown"
msgstr "I2P ýapmagy ýatyryň"
#: src/net/i2p/desktopgui/InternalTrayManager.java:363
#, java-format
msgid "Shutdown in {0}"
msgstr "{0} in ýapmak"
#: src/net/i2p/desktopgui/InternalTrayManager.java:365
msgid "Shutdown imminent"
msgstr "Öçürmek ýakyn"
#. status translations are in the console bundle
#: src/net/i2p/desktopgui/InternalTrayManager.java:370
msgid "Network"
msgstr "Tor"
#. Windows typically has tooltips; Linux (at least Ubuntu) doesn't
#: src/net/i2p/desktopgui/TrayManager.java:63
msgid "I2P: Right-click for menu"
msgstr "I2P: Menýu üçin sag basyň"

View File

@@ -0,0 +1,22 @@
plugins {
id 'war'
}
sourceSets {
main {
java {
srcDir 'java'
}
}
}
dependencies {
providedCompile project(':router')
providedCompile project(':apps:jetty')
providedCompile files('../../installer/lib/wrapper/all/wrapper.jar')
}
war {
archiveName 'jsonrpc.war'
webXml = file('web.xml')
}

View File

@@ -51,6 +51,7 @@
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.8" />
<property name="javac.release" value="8" />
<target name="compile" depends="builddep" >
<mkdir dir="./build" />
@@ -58,6 +59,7 @@
<javac
srcdir="./java"
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
release="${javac.release}"
includeAntRuntime="false"
encoding="UTF-8"
destdir="./build/obj"
@@ -77,6 +79,7 @@
sourcepath=""
srcdir="./java"
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
release="${javac.release}"
includeAntRuntime="false"
encoding="UTF-8"
destdir="./build/obj"
@@ -90,6 +93,8 @@
</target>
<target name="jar" depends="compile">
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar destfile="build/i2pcontrol.jar" basedir="./build/obj" includes="**/*.class" >
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
@@ -104,6 +109,8 @@
</target>
<target name="socketJar" depends="compileSocketJar">
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar destfile="build/i2pcontrol.jar" basedir="./build/obj" includes="**/*.class" >
<manifest>
<attribute name="Implementation-Version" value="${full.version}" />
@@ -118,6 +125,8 @@
</target>
<target name="war" depends="compile" >
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<war destfile="build/jsonrpc.war" webxml="web.xml" >
<classes dir="./build/obj" excludes="net/i2p/i2pcontrol/I2PControlController.class net/i2p/i2pcontrol/HostCheckHandler.class net/i2p/i2pcontrol/SocketController*.class" />
<manifest>

View File

@@ -55,7 +55,7 @@ import java.util.StringTokenizer;
* This handles the starting and stopping of Jetty
* from a single static class so it can be called via clients.config.
*
* This makes installation of a new eepsite a turnkey operation.
* This makes installation of a new I2P Site a turnkey operation.
*
* Usage: I2PControlController -d $PLUGIN [start|stop]
*

View File

@@ -145,8 +145,9 @@ public class JSONRPC2Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
httpServletResponse.setContentType("text/html");
setHeaders(httpServletResponse);
PrintWriter out = httpServletResponse.getWriter();
out.println("<html><head></head><body>");
out.println("<p>I2PControl RPC Service version " + I2PControlVersion.VERSION + " : Running");
if ("/password".equals(httpServletRequest.getServletPath())) {
out.println("<form method=\"POST\" action=\"password\">");
@@ -160,16 +161,19 @@ public class JSONRPC2Servlet extends HttpServlet {
"<input name=\"save\" type=\"submit\" value=\"Change API Password\">" +
"<p>If you forget the API password, stop i2pcontrol, delete the file <tt>" + _conf.getConfFile() +
"</tt>, and restart i2pcontrol.");
out.println("</form>");
} else {
out.println("<p><a href=\"password\">Change API Password</a>");
}
out.println("</body></html>");
out.close();
}
/** @since 0.12 */
private void doPasswordChange(HttpServletRequest req, HttpServletResponse httpServletResponse) throws ServletException, IOException {
httpServletResponse.setContentType("text/html");
setHeaders(httpServletResponse);
PrintWriter out = httpServletResponse.getWriter();
out.println("<html><head></head><body>");
String pw = req.getParameter("password");
if (pw == null)
pw = _secMan.DEFAULT_AUTH_PASSWORD;
@@ -194,6 +198,21 @@ public class JSONRPC2Servlet extends HttpServlet {
}
}
out.println("<p><a href=\"password\">Change API Password</a>");
out.println("</body></html>");
out.close();
}
/**
* @since 0.9.48
*/
private static void setHeaders(HttpServletResponse resp) {
resp.setContentType("text/html");
resp.setHeader("X-Frame-Options", "SAMEORIGIN");
resp.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self'; script-src 'self'; form-action 'self'; frame-ancestors 'self'; object-src 'none'; media-src 'none'");
resp.setHeader("X-XSS-Protection", "1; mode=block");
resp.setHeader("X-Content-Type-Options", "nosniff");
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Cache-Control","no-cache");
}
@Override

View File

@@ -6,13 +6,14 @@ sourceSets {
main {
java {
srcDir 'java/src'
srcDir 'java/build/messages-src'
}
}
}
dependencies {
compile project(':core')
compile project(':apps:systray')
providedCompile project(':apps:systray')
compile 'gnu.getopt:java-getopt:1.0.13'
providedCompile project(':apps:ministreaming')
providedCompile project(':apps:jetty')
@@ -34,10 +35,26 @@ artifacts {
archives i2psnarkJar
}
war {
into '.icons', {
from 'icons'
// Create the java files from the po files. The jar task will compile them.
// This requires gettext 0.19 or higher.
// We don't support the "slow way"
task bundle {
doLast {
if (!(new File("$buildDir/classes/java/main/org/klomp/snark/web/messages_de.class")).exists())
println "apps/i2psnark/java/bundle-messages.sh".execute().text
}
}
war.dependsOn bundle
war {
rootSpec.exclude('/org/klomp/snark/*.class')
rootSpec.exclude('/org/klomp/snark/bencode/**')
rootSpec.exclude('/org/klomp/snark/comments/**')
rootSpec.exclude('/org/klomp/snark/dht/**')
rootSpec.exclude('/org/klomp/snark/standalone/**')
from ('resources', {
into ".resources"
})
webInf {
into 'classes/org/klomp/snark/web'
from 'mime.properties'

View File

@@ -28,6 +28,7 @@
<!-- only used if not set by a higher build.xml -->
<property name="javac.compilerargs" value="" />
<property name="javac.version" value="1.8" />
<property name="javac.release" value="8" />
<property name="require.gettext" value="true" />
<property name="manifest.classpath.name" value="Class-Path" />
@@ -41,6 +42,7 @@
<javac
srcdir="./src"
debug="true" deprecation="on" source="${javac.version}" target="${javac.version}"
release="${javac.release}"
destdir="./build/obj"
encoding="UTF-8"
includeAntRuntime="false" >
@@ -164,6 +166,7 @@
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
release="${javac.release}"
includeAntRuntime="false"
encoding="UTF-8"
srcdir="build/messages-src" destdir="build/obj">
@@ -247,53 +250,51 @@
<!-- add css, image, and js files for standalone snark to the war -->
<target name="standalone_war" depends="war">
<mkdir dir="build/standalone-resources/.resources/themes/snark" />
<copy todir="build/standalone-resources/.resources/themes/snark" >
<fileset dir="../../../installer/resources/themes/snark/" />
<mkdir dir="build/standalone-resources/.resources/themes/" />
<copy todir="build/standalone-resources/.resources/themes/" >
<fileset dir="../resources/themes/" />
</copy>
<replace dir="build/standalone-resources/.resources/themes/snark"
<replace dir="build/standalone-resources/.resources/themes"
summary="true"
token="url(/themes/console/dark/images/"
value="url(/i2psnark/.resources/themes/snark/dark/images/" >
value="url(/i2psnark/.resources/themes/dark/images/" >
<include name="**/*.css" />
</replace>
<replace dir="build/standalone-resources/.resources/themes/snark"
<replace dir="build/standalone-resources/.resources/themes"
summary="true"
token="url(../../console/light/images/"
value="url(/i2psnark/.resources/themes/snark/light/images/" >
value="url(/i2psnark/.resources/themes/light/images/" >
<include name="**/*.css" />
</replace>
<replace dir="build/standalone-resources/.resources/themes/snark"
<replace dir="build/standalone-resources/.resources/themes"
summary="true"
token="url(/themes/console/light/images/"
value="url(/i2psnark/.resources/themes/snark/light/images/" >
value="url(/i2psnark/.resources/themes/light/images/" >
<include name="**/*.css" />
</replace>
<replace dir="build/standalone-resources/.resources/themes/snark"
<replace dir="build/standalone-resources/.resources/themes"
summary="true"
token="url(/themes/console/images/transparent.gif"
value="url(/i2psnark/.resources/themes/snark/ubergine/images/transparent.gif" >
value="url(/i2psnark/.resources/themes/ubergine/images/transparent.gif" >
<include name="**/*.css" />
</replace>
<replace dir="build/standalone-resources/.resources/themes/snark"
<replace dir="build/standalone-resources/.resources/themes"
summary="true"
token="url(/themes/console/images/info/"
value="url(/i2psnark/.resources/themes/snark/ubergine/images/" >
value="url(/i2psnark/.resources/themes/ubergine/images/" >
<include name="**/*.css" />
</replace>
<!-- Rather than pulling in all the console theme images, let's just specify the ones we need -->
<copy file="../../../installer/resources/themes/console/images/transparent.gif"
todir="build/standalone-resources/.resources/themes/snark/ubergine/images" />
<copy file="../../../installer/resources/themes/console/dark/images/header.png"
todir="build/standalone-resources/.resources/themes/snark/dark/images" />
<copy file="../../../installer/resources/themes/console/light/images/header.png"
todir="build/standalone-resources/.resources/themes/snark/light/images" />
<copy file="../../../installer/resources/themes/console/dark/images/camotile2.png"
todir="build/standalone-resources/.resources/themes/snark/dark/images" />
<copy file="../../../installer/resources/themes/console/images/info/errortriangle.png"
todir="build/standalone-resources/.resources/themes/snark/ubergine/images" />
<copy file="../../routerconsole/jsp/themes/console/images/transparent.gif"
todir="build/standalone-resources/.resources/themes/ubergine/images" />
<copy file="../../routerconsole/jsp/themes/console/dark/images/header.png"
todir="build/standalone-resources/.resources/themes/dark/images" />
<copy file="../../routerconsole/jsp/themes/console/light/images/header.png"
todir="build/standalone-resources/.resources/themes/light/images" />
<copy file="../../routerconsole/jsp/themes/console/images/info/errortriangle.png"
todir="build/standalone-resources/.resources/themes/ubergine/images" />
<mkdir dir="build/standalone-resources/.resources/js" />
<copy file="../../routerconsole/jsp/js/ajax.js" todir="build/standalone-resources/.resources/js" />

View File

@@ -10,6 +10,7 @@
#
# zzz - public domain
#
cd `dirname $0`
CLASS=org.klomp.snark.web.messages
TMPFILE=build/javafiles.txt
export TZ=UTC

View File

@@ -5,8 +5,10 @@ import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -57,7 +59,6 @@ public class I2PSnarkUtil {
private int _i2cpPort;
private final Map<String, String> _opts;
private volatile I2PSocketManager _manager;
private boolean _configured;
private volatile boolean _connecting;
private final Set<Hash> _banlist;
private int _maxUploaders;
@@ -84,6 +85,10 @@ public class I2PSnarkUtil {
public static final String PROP_MAX_BW = "i2cp.outboundBytesPerSecond";
public static final boolean DEFAULT_USE_DHT = true;
public static final String EEPGET_USER_AGENT = "I2PSnark";
private static final List<String> HIDDEN_I2CP_OPTS = Arrays.asList(new String[] {
PROP_MAX_BW, "inbound.length", "outbound.length", "inbound.quantity", "outbound.quantity"
});
public I2PSnarkUtil(I2PAppContext ctx) {
this(ctx, "i2psnark");
@@ -142,25 +147,34 @@ public class I2PSnarkUtil {
/** @since 0.9.1 */
public I2PAppContext getContext() { return _context; }
public boolean configured() { return _configured; }
/**
* @param i2cpHost may be null for no change
* @param i2cpPort may be 0 for no change
* @param opts may be null for no change
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public void setI2CPConfig(String i2cpHost, int i2cpPort, Map opts) {
if (i2cpHost != null)
_i2cpHost = i2cpHost;
if (i2cpPort > 0)
_i2cpPort = i2cpPort;
// can't remove any options this way...
if (opts != null)
_opts.putAll(opts);
if (opts != null) {
synchronized(_opts) {
// removed options...
for (Iterator<String> iter = _opts.keySet().iterator(); iter.hasNext(); ) {
String k = iter.next();
if (!HIDDEN_I2CP_OPTS.contains(k) && !opts.containsKey(k))
iter.remove();
}
_opts.putAll(opts);
}
}
// this updates the session options and tells the router
setMaxUpBW(_maxUpBW);
_configured = true;
}
public void setMaxUploaders(int limit) {
_maxUploaders = limit;
_configured = true;
}
/**
@@ -169,13 +183,16 @@ public class I2PSnarkUtil {
*/
public void setMaxUpBW(int limit) {
_maxUpBW = limit;
_opts.put(PROP_MAX_BW, Integer.toString(limit * (1024 * 6 / 5))); // add a little for overhead
_configured = true;
synchronized(_opts) {
_opts.put(PROP_MAX_BW, Integer.toString(limit * (1024 * 6 / 5))); // add a little for overhead
}
if (_manager != null) {
I2PSession sess = _manager.getSession();
if (sess != null) {
Properties newProps = new Properties();
newProps.putAll(_opts);
synchronized(_opts) {
newProps.putAll(_opts);
}
sess.updateOptions(newProps);
}
}
@@ -183,17 +200,24 @@ public class I2PSnarkUtil {
public void setMaxConnections(int limit) {
_maxConnections = limit;
_configured = true;
}
public void setStartupDelay(int minutes) {
_startupDelay = minutes;
_configured = true;
}
public String getI2CPHost() { return _i2cpHost; }
public int getI2CPPort() { return _i2cpPort; }
public Map<String, String> getI2CPOptions() { return _opts; }
/**
* @return a copy
*/
public Map<String, String> getI2CPOptions() {
synchronized(_opts) {
return new HashMap<String, String>(_opts);
}
}
public String getEepProxyHost() { return _proxyHost; }
public int getEepProxyPort() { return _proxyPort; }
public boolean getEepProxySet() { return _shouldProxy; }
@@ -225,9 +249,8 @@ public class I2PSnarkUtil {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Connecting to I2P", new Exception("I did it"));
Properties opts = _context.getProperties();
if (_opts != null) {
for (Map.Entry<String, String> entry : _opts.entrySet() )
opts.setProperty(entry.getKey(), entry.getValue());
synchronized(_opts) {
opts.putAll(_opts);
}
// override preference and start with two tunnels. IdleChecker will ramp up/down as necessary
String sin = opts.getProperty("inbound.quantity");

View File

@@ -49,7 +49,7 @@ class MagnetState {
infohash = iHash;
if (meta != null) {
metainfo = meta;
initialize(meta.getInfoBytes().length);
initialize(meta.getInfoBytesLength());
complete = true;
}
}

View File

@@ -24,6 +24,13 @@ public class MagnetURI {
public static final String MAGNET_FULL = MAGNET + "?xt=urn:btih:";
/** http://sponge.i2p/files/maggotspec.txt */
public static final String MAGGOT = "maggot://";
/**
* https://blog.libtorrent.org/2020/09/bittorrent-v2/
* TODO, dup param parsing, as a dual v1/v2 link
* will contain two xt params
* @since 0.9.48
*/
public static final String MAGNET_FULL_V2 = MAGNET + "?xt=urn:btmh:";
/**
* @param url non-null
@@ -35,6 +42,7 @@ public class MagnetURI {
if (url.startsWith(MAGNET)) {
// magnet:?xt=urn:btih:0691e40aae02e552cfcb57af1dca56214680c0c5&tr=http://tracker2.postman.i2p/announce.php
String xt = getParam("xt", url);
// TODO btmh
if (xt == null || !xt.startsWith("urn:btih:"))
throw new IllegalArgumentException();
ihash = xt.substring("urn:btih:".length());

View File

@@ -49,6 +49,9 @@ class Message
final static byte REJECT = 16; // Fast (BEP 6)
final static byte ALLOWED_FAST = 17; // Fast (BEP 6)
final static byte EXTENSION = 20; // BEP 10
final static byte HASH_REQUEST = 21; // BEP 52
final static byte HASHES = 22; // BEP 52
final static byte HASH_REJECT = 23; // BEP 52
// Not all fields are used for every message.
// KEEP_ALIVE doesn't have a real wire representation
@@ -278,6 +281,13 @@ class Message
return "REJECT(" + piece + ',' + begin + ',' + length + ')';
case ALLOWED_FAST:
return "ALLOWED_FAST(" + piece + ')';
// BEP 52 below here
case HASH_REQUEST:
return "HASH_REQUEST";
case HASHES:
return "HASHES";
case HASH_REJECT:
return "HASH_REJECT";
default:
return "UNKNOWN (" + type + ')';
}

View File

@@ -58,6 +58,7 @@ public class MetaInfo
private final String name_utf8;
private final List<List<String>> files;
private final List<List<String>> files_utf8;
private final List<String> attributes;
private final List<Long> lengths;
private final int piece_length;
private final byte[] piece_hashes;
@@ -67,7 +68,9 @@ public class MetaInfo
private final String comment;
private final String created_by;
private final long creation_date;
private final List<String> url_list;
private Map<String, BEValue> infoMap;
private int infoBytesLength;
/**
* Called by Storage when creating a new torrent from local data
@@ -77,10 +80,12 @@ public class MetaInfo
* @param lengths null for single-file torrent
* @param announce_list may be null
* @param created_by may be null
* @param url_list may be null
* @param comment may be null
*/
MetaInfo(String announce, String name, String name_utf8, List<List<String>> files, List<Long> lengths,
int piece_length, byte[] piece_hashes, long length, boolean privateTorrent,
List<List<String>> announce_list, String created_by)
List<List<String>> announce_list, String created_by, List<String> url_list, String comment)
{
this.announce = announce;
this.name = name;
@@ -93,9 +98,13 @@ public class MetaInfo
this.length = length;
this.privateTorrent = privateTorrent;
this.announce_list = announce_list;
this.comment = null;
this.comment = comment;
this.created_by = created_by;
this.creation_date = I2PAppContext.getGlobalContext().clock().now();
this.url_list = url_list;
// TODO BEP 52 hybrid torrent with piece layers, meta version and file tree
this.attributes = null;
// TODO if we add a parameter for other keys
//if (other != null) {
@@ -171,6 +180,18 @@ public class MetaInfo
}
}
// BEP 19
val = m.get("url-list");
if (val == null) {
this.url_list = null;
} else {
List<BEValue> bl1 = val.getList();
this.url_list = new ArrayList<String>(bl1.size());
for (BEValue bev : bl1) {
this.url_list.add(bev.getString());
}
}
// misc. optional top-level stuff
val = m.get("comment");
String st = null;
@@ -238,8 +259,18 @@ public class MetaInfo
piece_length = val.getInt();
val = info.get("pieces");
if (val == null)
if (val == null) {
// BEP 52
// We do the check here because a torrent file could be combined v1/v2,
// so a version 2 value isn't by itself fatal
val = info.get("meta version");
if (val != null) {
int version = val.getInt();
if (version != 1)
throw new InvalidBEncodingException("Version " + version + " torrent file not supported");
}
throw new InvalidBEncodingException("Missing piece bytes");
}
piece_hashes = val.getBytes();
val = info.get("length");
@@ -250,6 +281,7 @@ public class MetaInfo
files = null;
files_utf8 = null;
lengths = null;
attributes = null;
}
else
{
@@ -265,8 +297,9 @@ public class MetaInfo
throw new InvalidBEncodingException("zero size files list");
List<List<String>> m_files = new ArrayList<List<String>>(size);
List<List<String>> m_files_utf8 = new ArrayList<List<String>>(size);
List<List<String>> m_files_utf8 = null;
List<Long> m_lengths = new ArrayList<Long>(size);
List<String> m_attributes = null;
long l = 0;
for (int i = 0; i < list.size(); i++)
{
@@ -312,6 +345,7 @@ public class MetaInfo
val = desc.get("path.utf-8");
if (val != null) {
m_files_utf8 = new ArrayList<List<String>>(size);
path_list = val.getList();
path_length = path_list.size();
if (path_length > 0) {
@@ -322,11 +356,28 @@ public class MetaInfo
m_files_utf8.add(Collections.unmodifiableList(file));
}
}
// BEP 47
val = desc.get("attr");
if (val != null) {
String s = val.getString();
if (m_attributes == null) {
m_attributes = new ArrayList<String>(size);
for (int j = 0; j < i; j++) {
m_attributes.add("");
}
m_attributes.add(s);
}
} else {
if (m_attributes != null)
m_attributes.add("");
}
}
files = Collections.unmodifiableList(m_files);
files_utf8 = Collections.unmodifiableList(m_files_utf8);
files_utf8 = m_files_utf8 != null ? Collections.unmodifiableList(m_files_utf8) : null;
lengths = Collections.unmodifiableList(m_lengths);
length = l;
attributes = m_attributes;
}
info_hash = calculateInfoHash();
@@ -372,6 +423,15 @@ public class MetaInfo
return announce_list;
}
/**
* Returns a list of urls or null.
*
* @since 0.9.48
*/
public List<String> getWebSeedURLs() {
return url_list;
}
/**
* Returns the original 20 byte SHA1 hash over the bencoded info map.
*/
@@ -417,6 +477,16 @@ public class MetaInfo
return files;
}
/**
* Is this file a padding file?
* @since 0.9.48
*/
public boolean isPaddingFile(int filenum) {
if (attributes == null)
return false;
return attributes.get(filenum).indexOf('p') >= 0;
}
/**
* Returns a list of Longs indication the size of the individual
* files, or null if it is a single file. It has the same size as
@@ -552,6 +622,7 @@ public class MetaInfo
/**
* Returns the total length of the torrent in bytes.
* This includes any padding files.
*/
public long getTotalLength()
{
@@ -599,6 +670,8 @@ public class MetaInfo
if (announce_list != null)
m.put("announce-list", announce_list);
// misc. optional top-level stuff
if (url_list != null)
m.put("url-list", url_list);
if (comment != null)
m.put("comment", comment);
if (created_by != null)
@@ -612,11 +685,27 @@ public class MetaInfo
return BEncoder.bencode(m);
}
/** @since 0.8.4 */
/**
* Side effect: Caches infoBytesLength.
* @since 0.8.4
*/
public synchronized byte[] getInfoBytes() {
if (infoMap == null)
createInfoMap();
return BEncoder.bencode(infoMap);
byte[] rv = BEncoder.bencode(infoMap);
infoBytesLength = rv.length;
return rv;
}
/**
* The size of getInfoBytes().
* Cached.
* @since 0.9.48
*/
public synchronized int getInfoBytesLength() {
if (infoBytesLength > 0)
return infoBytesLength;
return getInfoBytes().length;
}
/** @return an unmodifiable view of the Map */
@@ -665,11 +754,19 @@ public class MetaInfo
file.put("path.utf-8", new BEValue(beufiles));
}
file.put("length", new BEValue(lengths.get(i)));
String attr = null;
if (attributes != null) {
attr = attributes.get(i);
if (attr.length() > 0)
file.put("attr", new BEValue(DataHelper.getASCII(attr)));
}
l.add(new BEValue(file));
}
info.put("files", new BEValue(l));
}
// TODO BEP 52 meta version and file tree
// TODO if we add the ability for other keys in the first constructor
//if (otherInfo != null)
// info.putAll(otherInfo);
@@ -706,7 +803,9 @@ public class MetaInfo
boolean error = false;
String created_by = null;
String announce = null;
Getopt g = new Getopt("Storage", args, "a:c:");
List<String> url_list = null;
String comment = null;
Getopt g = new Getopt("Storage", args, "a:c:m:w:");
try {
int c;
while ((c = g.getopt()) != -1) {
@@ -719,6 +818,16 @@ public class MetaInfo
created_by = g.getOptarg();
break;
case 'm':
comment = g.getOptarg();
break;
case 'w':
if (url_list == null)
url_list = new ArrayList<String>();
url_list.add(g.getOptarg());
break;
case '?':
case ':':
default:
@@ -731,7 +840,8 @@ public class MetaInfo
error = true;
}
if (error || args.length - g.getOptind() <= 0) {
System.err.println("Usage: MetaInfo [-a announceURL] [-c created-by] file.torrent [file2.torrent...]");
System.err.println("Usage: MetaInfo [-a announceURL] [-c created-by] [-m comment] [-w webseed-url]* file.torrent [file2.torrent...]");
System.exit(1);
}
for (int i = g.getOptind(); i < args.length; i++) {
InputStream in = null;
@@ -739,16 +849,21 @@ public class MetaInfo
try {
in = new FileInputStream(args[i]);
MetaInfo meta = new MetaInfo(in);
System.out.println(args[i] + "\nInfoHash: " + I2PSnarkUtil.toHex(meta.getInfoHash()) +
"\nAnnounce: " + meta.getAnnounce() +
"\nCreated By: " + meta.getCreatedBy());
if (created_by != null || announce != null) {
System.out.println(args[i] +
"\nInfoHash: " + I2PSnarkUtil.toHex(meta.getInfoHash()) +
"\nAnnounce: " + meta.getAnnounce() +
"\nWebSeed URLs: " + meta.getWebSeedURLs() +
"\nCreated By: " + meta.getCreatedBy() +
"\nComment: " + meta.getComment());
if (created_by != null || announce != null || url_list != null || comment != null) {
String cb = created_by != null ? created_by : meta.getCreatedBy();
String an = announce != null ? announce : meta.getAnnounce();
// changes/adds creation date, loses comment
String cm = comment != null ? comment : meta.getComment();
List<String> urls = url_list != null ? url_list : meta.getWebSeedURLs();
// changes/adds creation date
MetaInfo meta2 = new MetaInfo(an, meta.getName(), null, meta.getFiles(), meta.getLengths(),
meta.getPieceLength(0), meta.getPieceHashes(), meta.getTotalLength(), meta.isPrivate(),
meta.getAnnounceList(), cb);
meta.getAnnounceList(), cb, urls, cm);
java.io.File from = new java.io.File(args[i]);
java.io.File to = new java.io.File(args[i] + ".bak");
if (net.i2p.util.FileUtil.copy(from, to, true, false)) {
@@ -756,9 +871,12 @@ public class MetaInfo
out.write(meta2.getTorrentData());
out.close();
System.out.println("Modified " + from + " and backed up old file to " + to);
System.out.println(args[i] + "\nInfoHash: " + I2PSnarkUtil.toHex(meta2.getInfoHash()) +
"\nAnnounce: " + meta2.getAnnounce() +
"\nCreated By: " + meta2.getCreatedBy());
System.out.println(args[i] +
"\nInfoHash: " + I2PSnarkUtil.toHex(meta2.getInfoHash()) +
"\nAnnounce: " + meta2.getAnnounce() +
"\nWebSeed URLs: " + meta2.getWebSeedURLs() +
"\nCreated By: " + meta2.getCreatedBy() +
"\nComment: " + meta2.getComment());
} else {
System.out.println("Failed backup of " + from + " to " + to);
}

View File

@@ -42,14 +42,14 @@ import org.klomp.snark.bencode.InvalidBEncodingException;
public class Peer implements Comparable<Peer>
{
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(Peer.class);
protected final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(getClass());
// Identifying property, the peer id of the other side.
private final PeerID peerID;
private final byte[] my_id;
private final byte[] infohash;
/** will start out null in magnet mode */
private MetaInfo metainfo;
protected MetaInfo metainfo;
private Map<String, BEValue> handshakeMap;
// The data in/output streams set during the handshake and used by
@@ -61,8 +61,11 @@ public class Peer implements Comparable<Peer>
private final AtomicLong downloaded = new AtomicLong();
private final AtomicLong uploaded = new AtomicLong();
// Keeps state for in/out connections. Non-null when the handshake
// was successful, the connection setup and runs
/** `
* Keeps state for in/out connections. Non-null when the handshake
* was successful, the connection setup and runs.
* Do not access directly. All actions should be through Peer methods.
*/
volatile PeerState state;
/** shared across all peers on this torrent */
@@ -77,19 +80,18 @@ public class Peer implements Comparable<Peer>
final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds
final static int RATE_DEPTH = PeerCoordinator.RATE_DEPTH; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1};
private final long uploaded_old[] = {-1,-1,-1};
private final long downloaded_old[] = {-1,-1,-1};
private static final byte[] HANDSHAKE = DataHelper.getASCII("BitTorrent protocol");
// See BEP 4 for definitions
// bytes per bt spec: 0011223344556677
private static final long OPTION_EXTENSION = 0x0000000000100000l;
private static final long OPTION_FAST = 0x0000000000000004l;
//private static final long OPTION_DHT = 0x0000000000000001l;
/** we use a different bit since the compact format is different */
/* no, let's use an extension message
static final long OPTION_I2P_DHT = 0x0000000040000000l;
*/
//private static final long OPTION_AZMP = 0x1000000000000000l;
// hybrid support TODO
private static final long OPTION_V2 = 0x0000000000000010L;
private long options;
private final boolean _isIncoming;
private int _totalCommentsSent;
@@ -291,7 +293,7 @@ public class Peer implements Comparable<Peer>
if ((options & OPTION_EXTENSION) != 0) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Peer supports extensions, sending reply message");
int metasize = metainfo != null ? metainfo.getInfoBytes().length : -1;
int metasize = metainfo != null ? metainfo.getInfoBytesLength() : -1;
boolean pexAndMetadata = metainfo == null || !metainfo.isPrivate();
boolean dht = util.getDHT() != null;
boolean comment = util.utCommentsEnabled();
@@ -342,7 +344,6 @@ public class Peer implements Comparable<Peer>
private byte[] handshake(InputStream in, OutputStream out)
throws IOException
{
din = new DataInputStream(in);
dout = new DataOutputStream(out);
// Handshake write - header
@@ -367,6 +368,7 @@ public class Peer implements Comparable<Peer>
_log.debug("Wrote my shared hash and ID to " + toString());
// Handshake read - header
din = new DataInputStream(in);
byte b = din.readByte();
if (b != HANDSHAKE.length)
throw new IOException("Handshake failure, expected 19, got "
@@ -790,4 +792,12 @@ public class Peer implements Comparable<Peer>
void setTotalCommentsSent(int count) {
_totalCommentsSent = count;
}
/**
* @return false
* @since 0.9.49
*/
public boolean isWebPeer() {
return false;
}
}

View File

@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -152,6 +153,10 @@ class PeerCoordinator implements PeerListener
private static final long COMMENT_REQ_INTERVAL = 12*60*60*1000L;
private static final long COMMENT_REQ_DELAY = 60*60*1000L;
private static final int MAX_COMMENT_NOT_REQ = 10;
/** hostname to expire time, sync on this */
private Map<String, Long> _webPeerBans;
private static final long WEBPEER_BAN_TIME = 30*60*1000L;
/**
* @param metainfo null if in magnet mode
@@ -916,6 +921,7 @@ class PeerCoordinator implements PeerListener
// As connections are already up, new Pieces will
// not have their PeerID list populated, so do that.
for (Peer p : peers) {
// TODO don't access state directly
PeerState s = p.state;
if (s != null) {
BitField bf = s.bitfield;
@@ -1062,7 +1068,8 @@ class PeerCoordinator implements PeerListener
// just in case
removePartialPiece(piece);
// Oops. We didn't actually download this then... :(
downloaded.addAndGet(0 - metainfo.getPieceLength(piece));
// Reports of counter going negative?
//downloaded.addAndGet(0 - metainfo.getPieceLength(piece));
// Mark this peer as not having the piece. PeerState will update its bitfield.
for (Piece pc : wantedPieces) {
if (pc.getId() == piece) {
@@ -1299,6 +1306,7 @@ class PeerCoordinator implements PeerListener
if (++seeds >= 4)
break;
} else {
// TODO don't access state directly
PeerState state = pr.state;
if (state == null) continue;
BitField bf = state.bitfield;
@@ -1336,6 +1344,7 @@ class PeerCoordinator implements PeerListener
// Temporary? So PeerState never calls wantPiece() directly for now...
Piece piece = wantPiece(peer, havePieces, true);
if (piece != null) {
// TODO padding
return new PartialPiece(piece, metainfo.getPieceLength(piece.getId()), _util.getTempDir());
}
if (_log.shouldLog(Log.DEBUG))
@@ -1452,6 +1461,10 @@ class PeerCoordinator implements PeerListener
if (bev.getMap().get(ExtensionHandler.TYPE_PEX) != null) {
List<Peer> pList = peerList();
pList.remove(peer);
for (Iterator<Peer> iter = pList.iterator(); iter.hasNext(); ) {
if (iter.next().isWebPeer())
iter.remove();
}
if (!pList.isEmpty())
ExtensionHandler.sendPEX(peer, pList);
}
@@ -1749,5 +1762,43 @@ class PeerCoordinator implements PeerListener
public I2PSnarkUtil getUtil() {
return _util;
}
/**
* Ban a web peer for this torrent, for while or permanently.
* @param host the host name
* @since 0.9.49
*/
public synchronized void banWebPeer(String host, boolean isPermanent) {
if (_webPeerBans == null)
_webPeerBans = new HashMap<String, Long>(4);
Long time;
if (isPermanent) {
time = Long.valueOf(Long.MAX_VALUE);
} else {
long now = _util.getContext().clock().now();
time = Long.valueOf(now + WEBPEER_BAN_TIME);
}
Long old = _webPeerBans.put(host, time);
if (old != null && old.longValue() > time)
_webPeerBans.put(host, old);
}
/**
* Is a web peer banned?
* @param host the host name
* @since 0.9.49
*/
public synchronized boolean isWebPeerBanned(String host) {
if (_webPeerBans == null)
return false;
Long time = _webPeerBans.get(host);
if (time == null)
return false;
long now = _util.getContext().clock().now();
boolean rv = time.longValue() > now;
if (!rv)
_webPeerBans.remove(host);
return rv;
}
}

View File

@@ -227,6 +227,10 @@ public class PeerID implements Comparable<PeerID>
{
if (_toStringCache != null)
return _toStringCache;
if (id != null && DataHelper.eq(id, 0, WebPeer.IDBytes, 0, WebPeer.IDBytes.length)) {
_toStringCache = "WebSeed@" + Base32.encode(destHash) + ".b32.i2p";
return _toStringCache;
}
if (id == null || address == null)
return "unkn@" + Base64.encode(destHash).substring(0, 6);
int nonZero = 0;

View File

@@ -195,8 +195,10 @@ public class SnarkManager implements CompleteListener, ClientApp {
// ,"Exotrack", "http://blbgywsjubw3d2zih2giokakhe3o2cko7jtte4risb3hohbcoyva.b32.i2p/announce.php=http://exotrack.i2p/"
,"DgTrack", "http://w7tpbzncbcocrqtwwm3nezhnnsw4ozadvi2hmvzdhrqzfxfum7wa.b32.i2p/a=http://opentracker.dg2.i2p/"
// The following is ECDSA_SHA256_P256
,"TheBland", "http://s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq.b32.i2p/a=http://tracker.thebland.i2p/tracker/index.jsp"
,"psi's open tracker", "http://uajd4nctepxpac4c4bdyrdw7qvja2a5u3x25otfhkptcjgd53ioq.b32.i2p/announce=http://uajd4nctepxpac4c4bdyrdw7qvja2a5u3x25otfhkptcjgd53ioq.b32.i2p/"
//last up Sep. 19 2020
//,"TheBland", "http://s5ikrdyjwbcgxmqetxb3nyheizftms7euacuub2hic7defkh3xhq.b32.i2p/a=http://tracker.thebland.i2p/tracker/index.jsp"
//down for good
//,"psi's open tracker", "http://uajd4nctepxpac4c4bdyrdw7qvja2a5u3x25otfhkptcjgd53ioq.b32.i2p/announce=http://uajd4nctepxpac4c4bdyrdw7qvja2a5u3x25otfhkptcjgd53ioq.b32.i2p/"
//last up May 21 2019
// ,"C.Tracker", "http://ri5a27ioqd4vkik72fawbcryglkmwyy4726uu5j3eg6zqh2jswfq.b32.i2p/announce=http://tracker.crypthost.i2p/tracker/index.jsp",
};
@@ -205,8 +207,8 @@ public class SnarkManager implements CompleteListener, ClientApp {
public static final String DEFAULT_BACKUP_TRACKER = "http://opentracker.dg2.i2p/a";
/** URLs, comma-separated. Used for "announce to open trackers also" */
private static final String DEFAULT_OPENTRACKERS = DEFAULT_BACKUP_TRACKER +
(SigType.ECDSA_SHA256_P256.isAvailable() ? ",http://tracker.thebland.i2p/a" : "");
private static final String DEFAULT_OPENTRACKERS = DEFAULT_BACKUP_TRACKER; // +
//(SigType.ECDSA_SHA256_P256.isAvailable() ? ",http://tracker.thebland.i2p/a" : "");
public static final Set<String> DEFAULT_TRACKER_ANNOUNCES;
@@ -881,6 +883,31 @@ public class SnarkManager implements CompleteListener, ClientApp {
}
return theme;
}
/**
* Get the path to the preferred embedded icons for toImg, "solid/" for
* dark and light, "" for everything else.
*
* If you add a theme with a new icon set, then you need to add a
* corresponding condition here.
*
* @return String "solid/" or ""
* @since 0.9.48
*/
public String getThemeIconSet() {
String iconset;
String theme = getTheme();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Theme was: " + theme);
if (theme.equals("dark") || theme.equals("light")) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Using solid iconset.");
iconset = "solid/";
} else {
iconset = "";
}
return iconset;
}
/**
* Get all themes

View File

@@ -144,6 +144,30 @@ public class Storage implements Closeable
String created_by,
boolean privateTorrent, StorageListener listener)
throws IOException
{
this(util, baseFile, announce, announce_list, created_by, privateTorrent, null, null, listener);
}
/**
* Creates a storage from the existing file or directory.
* Creates an in-memory metainfo but does not save it to
* a file, caller must do that.
*
* Creates the metainfo, this may take a LONG time. BLOCKING.
*
* @param announce may be null
* @param listener may be null
* @param created_by may be null
* @param url_list may be null
* @param comment may be null
* @throws IOException when creating and/or checking files fails.
* @since 0.9.48
*/
public Storage(I2PSnarkUtil util, File baseFile, String announce,
List<List<String>> announce_list,
String created_by,
boolean privateTorrent, List<String> url_list, String comment, StorageListener listener)
throws IOException
{
_util = util;
_base = baseFile;
@@ -210,7 +234,7 @@ public class Storage implements Closeable
byte[] piece_hashes = fast_digestCreate();
metainfo = new MetaInfo(announce, baseFile.getName(), null, files,
lengthsList, piece_size, piece_hashes, total, privateTorrent,
announce_list, created_by);
announce_list, created_by, url_list, comment);
}
@@ -1364,6 +1388,7 @@ public class Storage implements Closeable
//rafs[i].write(bs, off + written, len);
pp.write(raf, written, len);
} catch (IOException ioe) {
try { tf.closeRAF(); } catch (IOException ioe2) {}
// get the file name in the logs
IOException ioe2 = new IOException("Error writing " + tf.RAFfile.getAbsolutePath());
ioe2.initCause(ioe);
@@ -1470,6 +1495,7 @@ public class Storage implements Closeable
raf.seek(start);
raf.readFully(bs, read, len);
} catch (IOException ioe) {
try { tf.closeRAF(); } catch (IOException ioe2) {}
// get the file name in the logs
IOException ioe2 = new IOException("Error reading " + tf.RAFfile.getAbsolutePath());
ioe2.initCause(ioe);
@@ -1685,7 +1711,9 @@ public class Storage implements Closeable
boolean error = false;
String created_by = null;
String announce = null;
Getopt g = new Getopt("Storage", args, "a:c:");
List<String> url_list = null;
String comment = null;
Getopt g = new Getopt("Storage", args, "a:c:m:w:");
try {
int c;
while ((c = g.getopt()) != -1) {
@@ -1698,6 +1726,16 @@ public class Storage implements Closeable
created_by = g.getOptarg();
break;
case 'm':
comment = g.getOptarg();
break;
case 'w':
if (url_list == null)
url_list = new ArrayList<String>();
url_list.add(g.getOptarg());
break;
case '?':
case ':':
default:
@@ -1710,7 +1748,7 @@ public class Storage implements Closeable
error = true;
}
if (error || args.length - g.getOptind() != 1) {
System.err.println("Usage: Storage [-a announceURL] [-c created-by] file-or-dir");
System.err.println("Usage: Storage [-a announceURL] [-c created-by] [-m comment] [-w webseed-url]* file-or-dir");
System.exit(1);
}
File base = new File(args[g.getOptind()]);
@@ -1719,7 +1757,7 @@ public class Storage implements Closeable
File file = null;
FileOutputStream out = null;
try {
Storage storage = new Storage(util, base, announce, null, created_by, false, null);
Storage storage = new Storage(util, base, announce, null, created_by, false, url_list, comment, null);
MetaInfo meta = storage.getMetaInfo();
file = new File(storage.getBaseName() + ".torrent");
out = new FileOutputStream(file);

View File

@@ -407,6 +407,8 @@ public class TrackerClient implements Runnable {
return;
}
int webPeers = getWebPeers();
// Local DHT tracker announce
DHT dht = _util.getDHT();
if (dht != null && (meta == null || !meta.isPrivate()))
@@ -438,7 +440,7 @@ public class TrackerClient implements Runnable {
}
// we could try and total the unique peers but that's too hard for now
snark.setTrackerSeenPeers(maxSeenPeers);
snark.setTrackerSeenPeers(maxSeenPeers + webPeers);
if (stop)
return;
@@ -720,6 +722,62 @@ public class TrackerClient implements Runnable {
return rv;
}
/**
* @return valid web peers from metainfo
* @since 0.9.49
*/
private int getWebPeers() {
if (meta == null)
return 0;
// prevent connecting out to a webseed for comments only
if (coordinator.getNeededLength() <= 0)
return 0;
List<String> urls = meta.getWebSeedURLs();
if (urls == null || urls.isEmpty())
return 0;
// Uncomment to skip multifile torrents
//if (meta.getLengths() != null)
// return 0;
List<Peer> peers = new ArrayList<Peer>(urls.size());
for (String url : urls) {
Hash h = getHostHash(url);
if (h == null)
continue;
try {
PeerID pID = new PeerID(h.getData(), _util);
byte[] id = new byte[20];
System.arraycopy(WebPeer.IDBytes, 0, id, 0, 12);
System.arraycopy(h.getData(), 0, id, 12, 8);
pID.setID(id);
URI uri = new URI(url);
String host = uri.getHost();
if (host == null)
continue;
if (coordinator.isWebPeerBanned(host)) {
if (_log.shouldWarn())
_log.warn("Skipping banned webseed " + url);
continue;
}
peers.add(new WebPeer(coordinator, uri, pID, snark.getMetaInfo()));
} catch (InvalidBEncodingException ibe) {
} catch (URISyntaxException use) {
}
}
if (peers.isEmpty())
return 0;
Random r = _util.getContext().random();
if (peers.size() > 1)
Collections.shuffle(peers, r);
Iterator<Peer> it = peers.iterator();
while ((!stop) && it.hasNext() && coordinator.needOutboundPeers()) {
Peer cur = it.next();
if (coordinator.addPeer(cur) && it.hasNext()) {
int delay = r.nextInt(DELAY_RAND) + DELAY_MIN;
try { Thread.sleep(delay); } catch (InterruptedException ie) {}
}
}
return peers.size();
}
/**
* Creates a thread for each tracker in parallel if tunnel is still open

View File

@@ -16,7 +16,7 @@
// ========================================================================
//
package org.klomp.snark.web;
package org.klomp.snark;
import java.io.UnsupportedEncodingException;
import java.net.URI;
@@ -35,9 +35,9 @@ import net.i2p.data.DataHelper;
* see UrlEncoded
*
* I2P modded from Jetty 8.1.15
* @since 0.9.15
* @since 0.9.15, moved from web in 0.9.49
*/
class URIUtil
public class URIUtil
{
/** Encode a URI path.

View File

@@ -0,0 +1,667 @@
package org.klomp.snark;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketEepGet;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.util.EepGet;
import net.i2p.util.Log;
/**
* BEP 19.
* Does not have an associated PeerState.
* All request tracking is done here.
* @since 0.9.49
*/
class WebPeer extends Peer implements EepGet.StatusListener {
private final PeerCoordinator _coordinator;
private final URI _uri;
// as received from coordinator
private final List<Request> outstandingRequests = new ArrayList<Request>();
private final boolean isMultiFile;
// needed?
private Request lastRequest;
private PeerListener listener;
private BitField bitfield;
private Thread thread;
private boolean connected;
private long lastRcvd;
private int maxRequests;
// to be recognized by the UI
public static final byte[] IDBytes = DataHelper.getASCII("WebSeedBEP19");
private static final long HEADER_TIMEOUT = 60*1000;
private static final long TOTAL_TIMEOUT = 10*60*1000;
private static final long INACTIVITY_TIMEOUT = 2*60*1000;
private static final long TARGET_FETCH_TIME = 2*60*1000;
// 128 KB
private static final int ABSOLUTE_MIN_REQUESTS = 8;
// 2 MB
private static final int ABSOLUTE_MAX_REQUESTS = 128;
private final int MIN_REQUESTS;
private final int MAX_REQUESTS;
/**
* Outgoing connection.
* Creates a disconnected peer given a PeerID, your own id and the
* relevant MetaInfo.
* @param uri must be http with .i2p host
* @param metainfo non-null
*/
public WebPeer(PeerCoordinator coord, URI uri, PeerID peerID, MetaInfo metainfo) {
super(peerID, null, null, metainfo);
// no use asking for more than the number of chunks in a piece
MAX_REQUESTS = Math.max(1, Math.min(ABSOLUTE_MAX_REQUESTS, metainfo.getPieceLength(0) / PeerState.PARTSIZE));
MIN_REQUESTS = Math.min(ABSOLUTE_MIN_REQUESTS, MAX_REQUESTS);
maxRequests = MIN_REQUESTS;
isMultiFile = metainfo.getLengths() != null;
_coordinator = coord;
// We'll assume the base path is already encoded, because
// it would have failed the checks in TrackerClient.getHostHash()
_uri = uri;
}
@Override
public String toString() {
return "WebSeed " + _uri;
}
/**
* @return socket debug string (for debug printing)
*/
@Override
public synchronized String getSocket() {
return toString() + ' ' + outstandingRequests.toString();
}
/**
* The hash code of a Peer is the hash code of the peerID.
*/
@Override
public int hashCode() {
return super.hashCode();
}
/**
* Two Peers are equal when they have the same PeerID.
* All other properties are ignored.
*/
@Override
public boolean equals(Object o) {
if (o instanceof WebPeer) {
WebPeer p = (WebPeer)o;
// TODO
return getPeerID().equals(p.getPeerID());
}
return false;
}
/**
* Runs the connection to the other peer. This method does not
* return until the connection is terminated.
*
* @param ignore our bitfield, ignore
* @param uploadOnly if we are complete with skipped files, i.e. a partial seed
*/
@Override
public void runConnection(I2PSnarkUtil util, PeerListener listener, BitField ignore,
MagnetState mState, boolean uploadOnly) {
if (uploadOnly)
return;
int fails = 0;
int successes = 0;
long dl = 0;
boolean notify = true;
ByteArrayOutputStream out = null;
// current requests per-loop
List<Request> requests = new ArrayList<Request>(8);
try {
if (!util.connected()) {
boolean ok = util.connect();
if (!ok)
return;
}
// This breaks out of the loop after any failure. TrackerClient will requeue eventually.
loop:
while (true) {
I2PSocketManager mgr = util.getSocketManager();
if (mgr == null)
return;
if (notify) {
synchronized(this) {
this.listener = listener;
bitfield = new BitField(metainfo.getPieces());
bitfield.setAll();
thread = Thread.currentThread();
connected = true;
}
listener.connected(this);
boolean want = listener.gotBitField(this, bitfield);
if (!want)
return;
listener.gotChoke(this, false);
notify = false;
}
synchronized(this) {
// clear out previous requests
if (!requests.isEmpty()) {
outstandingRequests.removeAll(requests);
requests.clear();
}
addRequest();
if (_log.shouldDebug())
_log.debug("Requests: " + outstandingRequests);
while (outstandingRequests.isEmpty()) {
if (_coordinator.getNeededLength() <= 0) {
if (_log.shouldDebug())
_log.debug("Complete: " + this);
break loop;
}
if (_log.shouldDebug())
_log.debug("No requests, sleeping: " + this);
connected = false;
out = null;
try {
this.wait();
} catch (InterruptedException ie) {
if (_log.shouldWarn())
_log.warn("Interrupted: " + this, ie);
break loop;
}
}
connected = true;
// Add current requests from outstandingRequests list and add to requests list.
// Do not remove from outstandingRequests until success.
lastRequest = outstandingRequests.get(0);
requests.add(lastRequest);
int piece = lastRequest.getPiece();
// Glue together additional requests if consecutive for a single piece.
// This will never glue together requests from different pieces,
// and the coordinator generally won't give us consecutive pieces anyway.
// Servers generally won't support multiple byte ranges anymore.
for (int i = 1; i < outstandingRequests.size(); i++) {
if (i >= maxRequests)
break;
Request r = outstandingRequests.get(i);
if (r.getPiece() == piece &&
lastRequest.off + lastRequest.len == r.off) {
requests.add(r);
lastRequest = r;
} else {
// all requests for a piece should be together, but not in practice
// as orphaned requests can get in-between
//break;
}
}
}
// total values
Request first = requests.get(0);
Request last = requests.get(requests.size() - 1);
int piece = first.getPiece();
int off = first.off;
long toff = (((long) piece) * metainfo.getPieceLength(0)) + off;
int tlen = (last.off - first.off) + last.len;
long start = System.currentTimeMillis();
///// TODO direct to file, not in-memory
if (out == null)
out = new ByteArrayOutputStream(tlen);
else
out.reset();
int filenum = -1;
// Loop for each file if multifile and crosses file boundaries.
// Once only for single file.
while (out.size() < tlen) {
// need these three things:
// url to fetch
String url;
// offset in fetched file
long foff;
// length to fetch, will be adjusted if crossing a file boundary
int flen = tlen - out.size();
if (isMultiFile) {
// multifile
List<Long> lengths = metainfo.getLengths();
long limit = 0;
if (filenum < 0) {
// find the first file number and limit
// inclusive
long fstart = 0;
// exclusive
long fend = 0;
foff = 0; // keep compiler happy, will always be re-set
for (int f = 0; f < lengths.size(); f++) {
long filelen = lengths.get(f).longValue();
fend = fstart + filelen;
if (toff < fend) {
filenum = f;
foff = toff - fstart;
limit = fend - toff;
break;
}
fstart += filelen;
}
if (filenum < 0)
throw new IllegalStateException(lastRequest.toString());
} else {
// next file
filenum++;
foff = 0;
limit = lengths.get(filenum).longValue();
}
if (limit > 0 && flen > limit)
flen = (int) limit;
if (metainfo.isPaddingFile(filenum)) {
for (int i = 0; i < flen; i++) {
out.write((byte) 0);
}
if (_log.shouldDebug())
_log.debug("Skipped padding file " + filenum);
continue;
}
// build url
String uri = _uri.toString();
StringBuilder buf = new StringBuilder(uri.length() + 128);
buf.append(uri);
if (!uri.endsWith("/"))
buf.append('/');
// See BEP 19 rules
URIUtil.encodePath(buf, metainfo.getName());
List<String> path = metainfo.getFiles().get(filenum);
for (int i = 0; i < path.size(); i++) {
buf.append('/');
URIUtil.encodePath(buf, path.get(i));
}
url = buf.toString();
} else {
// single file
// See BEP 19 rules
String uri = _uri.toString();
if (uri.endsWith("/"))
url = uri + URIUtil.encodePath(metainfo.getName());
else
url = uri;
foff = toff;
flen = tlen;
}
// do the fetch
EepGet get = new I2PSocketEepGet(util.getContext(), mgr, 0, flen, flen, null, out, url);
get.addHeader("User-Agent", I2PSnarkUtil.EEPGET_USER_AGENT);
get.addHeader("Range", "bytes=" + foff + '-' + (foff + flen - 1));
get.addStatusListener(this);
int osz = out.size();
if (_log.shouldDebug())
_log.debug("Fetching piece: " + piece + " offset: " + off + " file offset: " + foff + " len: " + flen + " from " + url);
if (get.fetch(HEADER_TIMEOUT, TOTAL_TIMEOUT, INACTIVITY_TIMEOUT)) {
int resp = get.getStatusCode();
if (resp != 200 && resp != 206) {
fail(url, resp);
return;
}
int sz = out.size() - osz;
if (sz != flen) {
if (_log.shouldWarn())
_log.warn("Fetch of " + url + " received: " + sz + " expected: " + flen);
return;
}
} else {
if (out.size() > 0) {
// save any complete chunks received
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(out.toByteArray()));
for (Iterator<Request> iter = requests.iterator(); iter.hasNext(); ) {
Request req = iter.next();
if (dis.available() < req.len)
break;
req.read(dis);
iter.remove();
if (_log.shouldWarn())
_log.warn("Saved chunk " + req + " recvd before failure");
}
}
int resp = get.getStatusCode();
fail(url, resp);
return;
}
successes++;
dl += flen;
if (!isMultiFile)
break;
} // for each file
// all data received successfully, now process it
if (_log.shouldDebug())
_log.debug("Fetch of piece: " + piece + " chunks: " + requests.size() + " offset: " + off + " torrent offset: " + toff + " len: " + tlen + " successful");
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(out.toByteArray()));
for (Request req : requests) {
req.read(dis);
}
PartialPiece pp = last.getPartialPiece();
synchronized(pp) {
// Last chunk needed for this piece?
if (pp.getLength() == pp.getDownloaded()) {
if (listener.gotPiece(this, pp)) {
if (_log.shouldDebug())
_log.debug("Got " + piece + ": " + this);
} else {
if (_log.shouldWarn())
_log.warn("Got BAD " + piece + " from " + this);
return;
}
} else {
// piece not complete
}
}
long time = lastRcvd - start;
if (time < TARGET_FETCH_TIME)
maxRequests = Math.min(MAX_REQUESTS, 2 * maxRequests);
else if (time > 2 * TARGET_FETCH_TIME)
maxRequests = Math.max(MIN_REQUESTS, maxRequests / 2);
} // request loop
} catch(IOException eofe) {
if (_log.shouldWarn())
_log.warn(toString(), eofe);
} finally {
List<Request> pcs = returnPartialPieces();
synchronized(this) {
connected = false;
outstandingRequests.clear();
}
requests.clear();
if (!pcs.isEmpty())
listener.savePartialPieces(this, pcs);
listener.disconnected(this);
disconnect();
if (_log.shouldWarn())
_log.warn("Completed, successful fetches: " + successes + " downloaded: " + dl + " for " + this);
}
}
private void fail(String url, int resp) {
if (_log.shouldWarn())
_log.warn("Fetch of " + url + " failed, rc: " + resp);
if (resp == 301 || resp == 308 ||
resp == 401 || resp == 403 || resp == 404 || resp == 410 || resp == 414 || resp == 416 || resp == 451) {
// ban forever
_coordinator.banWebPeer(_uri.getHost(), true);
if (_log.shouldWarn())
_log.warn("Permanently banning the webseed " + url);
} else if (resp == 429 || resp == 503) {
// ban for a while
_coordinator.banWebPeer(_uri.getHost(), false);
if (_log.shouldWarn())
_log.warn("Temporarily banning the webseed " + url);
}
}
@Override
public int getMaxPipeline() {
return maxRequests;
}
@Override
public boolean isConnected() {
synchronized(this) {
return connected;
}
}
@Override
synchronized void disconnect() {
if (thread != null)
thread.interrupt();
}
@Override
public void have(int piece) {}
@Override
void cancel(int piece) {}
@Override
void request() {
addRequest();
}
@Override
public boolean isInterested() {
return false;
}
@Deprecated
@Override
public void setInteresting(boolean interest) {}
@Override
public boolean isInteresting() {
return true;
}
@Override
public void setChoking(boolean choke) {}
@Override
public boolean isChoking() {
return false;
}
@Override
public boolean isChoked() {
return false;
}
@Override
public long getInactiveTime() {
if (lastRcvd <= 0)
return -1;
long now = System.currentTimeMillis();
return now - lastRcvd;
}
@Override
public long getMaxInactiveTime() {
return PeerCoordinator.MAX_INACTIVE;
}
@Override
public void keepAlive() {}
@Override
public void retransmitRequests() {}
@Override
public int completed() {
return metainfo.getPieces();
}
@Override
public boolean isCompleted() {
return true;
}
/**
* @return true
* @since 0.9.49
*/
@Override
public boolean isWebPeer() {
return false;
}
// private methods below here implementing parts of PeerState
private synchronized void addRequest() {
boolean more_pieces = true;
while (more_pieces) {
more_pieces = outstandingRequests.size() < getMaxPipeline();
// We want something and we don't have outstanding requests?
if (more_pieces && lastRequest == null) {
// we have nothing in the queue right now
more_pieces = requestNextPiece();
} else if (more_pieces) {
// We want something
int pieceLength;
boolean isLastChunk;
pieceLength = metainfo.getPieceLength(lastRequest.getPiece());
isLastChunk = lastRequest.off + lastRequest.len == pieceLength;
// Last part of a piece?
if (isLastChunk) {
more_pieces = requestNextPiece();
} else {
PartialPiece nextPiece = lastRequest.getPartialPiece();
int nextBegin = lastRequest.off + PeerState.PARTSIZE;
int maxLength = pieceLength - nextBegin;
int nextLength = maxLength > PeerState.PARTSIZE ? PeerState.PARTSIZE
: maxLength;
Request req = new Request(nextPiece,nextBegin, nextLength);
outstandingRequests.add(req);
lastRequest = req;
this.notifyAll();
}
}
}
}
/**
* Starts requesting first chunk of next piece. Returns true if
* something has been added to the requests, false otherwise.
*/
private synchronized boolean requestNextPiece() {
// Check for adopting an orphaned partial piece
PartialPiece pp = listener.getPartialPiece(this, bitfield);
if (pp != null) {
// Double-check that r not already in outstandingRequests
if (!getRequestedPieces().contains(Integer.valueOf(pp.getPiece()))) {
Request r = pp.getRequest();
outstandingRequests.add(r);
lastRequest = r;
this.notifyAll();
return true;
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Got dup from coord: " + pp);
pp.release();
}
}
// failsafe
// However this is bad as it thrashes the peer when we change our mind
// Ticket 691 cause here?
if (outstandingRequests.isEmpty())
lastRequest = null;
/*
// If we are not in the end game, we may run out of things to request
// because we are asking other peers. Set not-interesting now rather than
// wait for those other requests to be satisfied via havePiece()
if (interesting && lastRequest == null) {
interesting = false;
out.sendInterest(false);
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " nothing more to request, now uninteresting");
}
*/
return false;
}
/**
* @return all pieces we are currently requesting, or empty Set
*/
private synchronized Set<Integer> getRequestedPieces() {
Set<Integer> rv = new HashSet<Integer>(outstandingRequests.size() + 1);
for (Request req : outstandingRequests) {
rv.add(Integer.valueOf(req.getPiece()));
}
return rv;
}
/**
* @return index in outstandingRequests or -1
*/
private synchronized int getFirstOutstandingRequest(int piece) {
for (int i = 0; i < outstandingRequests.size(); i++) {
if (outstandingRequests.get(i).getPiece() == piece)
return i;
}
return -1;
}
private synchronized List<Request> returnPartialPieces() {
Set<Integer> pcs = getRequestedPieces();
List<Request> rv = new ArrayList<Request>(pcs.size());
for (Integer p : pcs) {
Request req = getLowestOutstandingRequest(p.intValue());
if (req != null) {
PartialPiece pp = req.getPartialPiece();
synchronized(pp) {
int dl = pp.getDownloaded();
if (req.off != dl)
req = new Request(pp, dl);
}
rv.add(req);
}
}
outstandingRequests.clear();
return rv;
}
private synchronized Request getLowestOutstandingRequest(int piece) {
Request rv = null;
int lowest = Integer.MAX_VALUE;
for (Request r : outstandingRequests) {
if (r.getPiece() == piece && r.off < lowest) {
lowest = r.off;
rv = r;
}
}
return rv;
}
// EepGet status listeners to maintain the state for the web page
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {
lastRcvd = System.currentTimeMillis();
downloaded(currentWrite);
listener.downloaded(this, currentWrite);
}
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) {}
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {}
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {}
public void headerReceived(String url, int attemptNum, String key, String val) {}
public void attempting(String url) {}
// End of EepGet status listeners
}

View File

@@ -37,20 +37,6 @@ import net.i2p.data.DataHelper;
public class BEncoder
{
public static byte[] bencode(Object o) throws IllegalArgumentException
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bencode(o, baos);
return baos.toByteArray();
}
catch (IOException ioe)
{
throw new InternalError(ioe.toString());
}
}
public static void bencode(Object o, OutputStream out)
throws IOException, IllegalArgumentException
{
@@ -72,40 +58,12 @@ public class BEncoder
throw new IllegalArgumentException("Cannot bencode: " + o.getClass());
}
public static byte[] bencode(String s)
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bencode(s, baos);
return baos.toByteArray();
}
catch (IOException ioe)
{
throw new InternalError(ioe.toString());
}
}
public static void bencode(String s, OutputStream out) throws IOException
{
byte[] bs = s.getBytes("UTF-8");
bencode(bs, out);
}
public static byte[] bencode(Number n)
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bencode(n, baos);
return baos.toByteArray();
}
catch (IOException ioe)
{
throw new InternalError(ioe.toString());
}
}
public static void bencode(Number n, OutputStream out) throws IOException
{
out.write('i');
@@ -114,20 +72,6 @@ public class BEncoder
out.write('e');
}
public static byte[] bencode(List<?> l)
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bencode(l, baos);
return baos.toByteArray();
}
catch (IOException ioe)
{
throw new InternalError(ioe.toString());
}
}
public static void bencode(List<?> l, OutputStream out) throws IOException
{
out.write('l');
@@ -137,20 +81,6 @@ public class BEncoder
out.write('e');
}
public static byte[] bencode(byte[] bs)
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bencode(bs, baos);
return baos.toByteArray();
}
catch (IOException ioe)
{
throw new InternalError(ioe.toString());
}
}
public static void bencode(byte[] bs, OutputStream out) throws IOException
{
String l = Integer.toString(bs.length);
@@ -216,7 +146,8 @@ public class BEncoder
if (l != null) {
// Keys must be sorted. XXX - This is not the correct order.
// Spec says to sort by bytes, not lexically
Collections.sort(l);
if (l.size() > 1)
Collections.sort(l);
for (String key : l) {
bencode(key, out);
bencode(m.get(key), out);
@@ -224,7 +155,8 @@ public class BEncoder
} else if (b != null) {
// Works for arrays of equal lengths, otherwise is probably not
// what the bittorrent spec intends.
Collections.sort(b, new BAComparator());
if (b.size() > 1)
Collections.sort(b, new BAComparator());
for (byte[] key : b) {
bencode(key, out);
bencode(m.get(key), out);

View File

@@ -42,6 +42,8 @@ import net.i2p.util.Log;
import net.i2p.util.SecureFile;
import net.i2p.util.SystemVersion;
import org.klomp.snark.URIUtil;
/* ------------------------------------------------------------ */
/**
@@ -472,6 +474,8 @@ class BasicServlet extends HttpServlet
/* ------------------------------------------------------------ */
public InputStream getInputStream() throws IOException
{
if (getContentLength() > 4*1024*1024)
return new BufferedInputStream(new FileInputStream(_file), 64*1024);
return new BufferedInputStream(new FileInputStream(_file));
}

View File

@@ -51,6 +51,7 @@ import org.klomp.snark.SnarkManager;
import org.klomp.snark.Storage;
import org.klomp.snark.Tracker;
import org.klomp.snark.TrackerClient;
import org.klomp.snark.URIUtil;
import org.klomp.snark.dht.DHT;
import org.klomp.snark.comments.Comment;
import org.klomp.snark.comments.CommentSet;
@@ -201,10 +202,7 @@ public class I2PSnarkServlet extends BasicServlet {
return;
}
if (_context.isRouterContext())
_themePath = "/themes/snark/" + _manager.getTheme() + '/';
else
_themePath = _contextPath + WARBASE + "themes/snark/" + _manager.getTheme() + '/';
_themePath = _contextPath + WARBASE + "themes/" + _manager.getTheme() + '/';
_imgPath = _themePath + "images/";
req.setCharacterEncoding("UTF-8");
@@ -463,7 +461,7 @@ public class I2PSnarkServlet extends BasicServlet {
*/
private boolean writeTorrents(PrintWriter out, HttpServletRequest req, boolean canWrite) throws IOException {
/** dl, ul, down rate, up rate, peers, size */
final long stats[] = {0,0,0,0,0,0};
final long stats[] = new long[6];
String peerParam = req.getParameter("p");
String stParam = req.getParameter("st");
@@ -1088,6 +1086,12 @@ public class I2PSnarkServlet extends BasicServlet {
// b32
newURL = newURL.toUpperCase(Locale.US);
addMagnet(MagnetURI.MAGNET_FULL + newURL, dir);
} else if (newURL.length() == 68 && newURL.startsWith("1220") &&
newURL.replaceAll("[a-fA-F0-9]", "").length() == 0) {
// hex v2 multihash
// TODO
_manager.addMessage("Version 2 info hashes are not supported");
//addMagnet(MagnetURI.MAGNET_FULL_V2 + newURL, dir);
} else {
// try as file path, hopefully we're on the same box
if (newURL.startsWith("file://"))
@@ -1141,8 +1145,8 @@ public class I2PSnarkServlet extends BasicServlet {
try { if (in != null) in.close(); } catch (IOException ioe) {}
}
} else {
_manager.addMessage(_t("Invalid URL: Must start with \"http://\", \"{0}\", or \"{1}\"",
MagnetURI.MAGNET, MagnetURI.MAGGOT));
_manager.addMessage(_t("Invalid URL: Must start with \"{0}\" or \"{1}\"",
"http://", MagnetURI.MAGNET));
}
}
} else {
@@ -1989,33 +1993,38 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(_t("Peer attached to swarm"));
out.write("\"></td><td colspan=\"5\">");
PeerID pid = peer.getPeerID();
String ch = pid != null ? pid.toString().substring(0, 4) : "????";
String client;
if ("AwMD".equals(ch))
client = _t("I2PSnark");
else if ("LUJJ".equals(ch))
client = "BiglyBT" + getAzVersion(pid.getID());
else if ("LUFa".equals(ch))
client = "Vuze" + getAzVersion(pid.getID());
else if ("LVhE".equals(ch))
client = "XD" + getAzVersion(pid.getID());
else if ("ZV".equals(ch.substring(2,4)) || "VUZP".equals(ch))
client = "Robert" + getRobtVersion(pid.getID());
else if (ch.startsWith("LV")) // LVCS 1.0.2?; LVRS 1.0.4
client = "Transmission" + getAzVersion(pid.getID());
else if ("LUtU".equals(ch))
client = "KTorrent" + getAzVersion(pid.getID());
else if ("CwsL".equals(ch))
client = "I2PSnarkXL";
else if ("BFJT".equals(ch))
client = "I2PRufus";
else if ("TTMt".equals(ch))
client = "I2P-BT";
else
client = _t("Unknown") + " (" + ch + ')';
out.write(client + "&nbsp;<tt title=\"");
out.write(_t("Destination (identity) of peer"));
out.write("\">" + peer.toString().substring(5, 9)+ "</tt>");
String ch = pid != null ? pid.toString() : "????";
if (ch.startsWith("WebSeed@")) {
out.write(ch);
} else {
ch = ch.substring(0, 4);
String client;
if ("AwMD".equals(ch))
client = _t("I2PSnark");
else if ("LUJJ".equals(ch))
client = "BiglyBT" + getAzVersion(pid.getID());
else if ("LUFa".equals(ch))
client = "Vuze" + getAzVersion(pid.getID());
else if ("LVhE".equals(ch))
client = "XD" + getAzVersion(pid.getID());
else if ("ZV".equals(ch.substring(2,4)) || "VUZP".equals(ch))
client = "Robert" + getRobtVersion(pid.getID());
else if (ch.startsWith("LV")) // LVCS 1.0.2?; LVRS 1.0.4
client = "Transmission" + getAzVersion(pid.getID());
else if ("LUtU".equals(ch))
client = "KTorrent" + getAzVersion(pid.getID());
else if ("CwsL".equals(ch))
client = "I2PSnarkXL";
else if ("BFJT".equals(ch))
client = "I2PRufus";
else if ("TTMt".equals(ch))
client = "I2P-BT";
else
client = _t("Unknown") + " (" + ch + ')';
out.write(client + "&nbsp;<tt title=\"");
out.write(_t("Destination (identity) of peer"));
out.write("\">" + peer.toString().substring(5, 9)+ "</tt>");
}
if (showDebug) {
long t = peer.getInactiveTime();
if (t >= 5000)
@@ -2298,7 +2307,7 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(_t("From URL"));
out.write(":<td><input type=\"text\" name=\"nofilter_newURL\" size=\"85\" value=\"" + newURL + "\" spellcheck=\"false\"" +
" title=\"");
out.write(_t("Enter the torrent file download URL (I2P only), magnet link, maggot link, or info hash"));
out.write(_t("Enter the torrent file download URL (I2P only), magnet link, or info hash"));
out.write("\">\n");
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
@@ -2470,8 +2479,8 @@ public class I2PSnarkServlet extends BasicServlet {
if (!_context.isRouterContext()) {
try {
// class only in standalone builds
Class helper = Class.forName("org.klomp.snark.standalone.ConfigUIHelper");
Method getLangSettings = helper.getMethod("getLangSettings", new Class[] {I2PAppContext.class});
Class<?> helper = Class.forName("org.klomp.snark.standalone.ConfigUIHelper");
Method getLangSettings = helper.getMethod("getLangSettings", I2PAppContext.class);
String langSettings = (String) getLangSettings.invoke(null, _context);
// If we get to here, we have the language settings
out.write("<tr><td>");
@@ -2801,6 +2810,10 @@ public class I2PSnarkServlet extends BasicServlet {
* @since 0.8.4
*/
private void addMagnet(String url, File dataDir) {
if (url.startsWith(MagnetURI.MAGNET_FULL_V2)) {
_manager.addMessage("Version 2 magnet links are not supported");
return;
}
try {
MagnetURI magnet = new MagnetURI(_manager.util(), url);
String name = magnet.getName();
@@ -3169,9 +3182,34 @@ public class I2PSnarkServlet extends BasicServlet {
}
buf.append("</td></tr>\n");
}
}
if (meta != null) {
List<String> weblist = meta.getWebSeedURLs();
if (weblist != null) {
List<String> wlist = new ArrayList<String>(weblist.size());
// strip non-i2p web seeds
for (String s : weblist) {
if (isI2PTracker(s))
wlist.add(s);
}
if (!wlist.isEmpty()) {
buf.append("<tr><td>");
toThemeImg(buf, "details");
buf.append("</td><td><b>")
.append(_t("Web Seeds")).append("</b></td><td>");
boolean more = false;
for (String s : wlist) {
buf.append("<span class=\"info_tracker\">");
if (more)
buf.append(' ');
else
more = true;
buf.append(getShortTrackerLink(DataHelper.stripHTML(s), snark.getInfoHash()));
buf.append("</span> ");
}
buf.append("</td></tr>\n");
}
}
String com = meta.getComment();
if (com != null && com.length() > 0) {
if (com.length() > 1024)
@@ -3278,6 +3316,7 @@ public class I2PSnarkServlet extends BasicServlet {
else
buf.append(_t("Complete")).append("</b>");
buf.append("</td><td><span>");
// TODO adjust for padding files
buf.append("<b>")
.append(_t("Size"))
.append(":</b> ")
@@ -3296,6 +3335,7 @@ public class I2PSnarkServlet extends BasicServlet {
} else {
buf.append('0');
}
// TODO adjust for padding files
// not including skipped files, but -1 when not running
long needed = snark.getNeededLength();
if (needed < 0) {
@@ -3309,6 +3349,7 @@ public class I2PSnarkServlet extends BasicServlet {
.append(":</b> ")
.append(formatSize(needed));
}
// TODO adjust for padding files
long skipped = snark.getSkippedLength();
if (skipped > 0) {
buf.append("</span>&nbsp;<span>");
@@ -3317,9 +3358,8 @@ public class I2PSnarkServlet extends BasicServlet {
.append(":</b> ")
.append(formatSize(skipped));
}
if (meta != null) {
List<List<String>> files = meta.getFiles();
int fileCount = files != null ? files.size() : 1;
if (storage != null) {
int fileCount = storage.getFileCount();
buf.append("</span>&nbsp;<span>");
buf.append("<b>")
.append(_t("Files"))
@@ -3427,14 +3467,14 @@ public class I2PSnarkServlet extends BasicServlet {
if (isAudio)
buf.append("<audio");
else
buf.append("<video");
buf.append("<div class=\"video-wrapper\"><video class=\"video\"");
// strip trailing slash
String path = base.substring(0, base.length() - 1);
buf.append(" controls><source src=\"").append(path).append("\" type=\"").append(mime).append("\">");
if (isAudio)
buf.append("</audio>");
else
buf.append("</video>");
buf.append("</video></div>");
}
}
if (er || ec)
@@ -3451,7 +3491,16 @@ public class I2PSnarkServlet extends BasicServlet {
long[] remainingArray = (arrays != null) ? arrays[0] : null;
long[] previewArray = (arrays != null) ? arrays[1] : null;
for (int i = 0; i < ls.length; i++) {
fileList.add(new Sorters.FileAndIndex(ls[i], storage, remainingArray, previewArray));
File f = ls[i];
if (isTopLevel) {
// Hide (assumed) padding directory if it's in the filesystem.
// Storage now will not create padding files, but
// may have been created by an old version or other client.
String n = f.getName();
if ((n.equals(".pad") || n.equals("_pad")) && f.isDirectory())
continue;
}
fileList.add(new Sorters.FileAndIndex(f, storage, remainingArray, previewArray));
}
boolean showSort = fileList.size() > 1;
@@ -3612,7 +3661,7 @@ public class I2PSnarkServlet extends BasicServlet {
}
String path = addPaths(decodedBase, item.getName());
if (item.isDirectory() && !path.endsWith("/"))
if (fai.isDirectory && !path.endsWith("/"))
path=addPaths(path,"/");
path = encodePath(path);
String icon = toIcon(item);
@@ -3638,7 +3687,7 @@ public class I2PSnarkServlet extends BasicServlet {
if (isAudio)
buf.append("<audio");
else
buf.append("<video");
buf.append("<div class=\"video-wrapper\"><video class=\"video\"");
buf.append(" controls><source src=\"").append(ppath).append("\" type=\"").append(mime).append("\">");
}
buf.append("<a href=\"").append(ppath).append("\">");
@@ -3652,7 +3701,7 @@ public class I2PSnarkServlet extends BasicServlet {
if (isAudio)
buf.append("</audio>");
else if (isVideo)
buf.append("</video>");
buf.append("</video></div>");
} else {
buf.append(toImg(icon));
}
@@ -3672,14 +3721,14 @@ public class I2PSnarkServlet extends BasicServlet {
if (preview != null)
buf.append(preview);
buf.append("</td><td align=right class=\"snarkFileSize\">");
if (!item.isDirectory())
if (!fai.isDirectory)
buf.append(formatSize(length));
buf.append("</td><td class=\"snarkFileStatus\">");
buf.append(status);
buf.append("</td>");
if (showPriority) {
buf.append("<td class=\"priority\">");
if ((!complete) && (!item.isDirectory())) {
if ((!complete) && (!fai.isDirectory)) {
if (!inOrder) {
buf.append("<label class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">" +
"\n<input type=\"radio\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
@@ -4202,7 +4251,7 @@ public class I2PSnarkServlet extends BasicServlet {
* @since 0.8.2
*/
private String toImg(String icon, String altText) {
return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"" + _contextPath + WARBASE + "icons/" + icon + ".png\">";
return "<img alt=\"" + altText + "\" height=\"16\" width=\"16\" src=\"" + _contextPath + WARBASE + "icons/" + _manager.getThemeIconSet() + icon + ".png?" + CoreVersion.VERSION + "\">";
}
/**

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 605 B

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 580 B

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 613 B

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