Compare commits

...

680 Commits

Author SHA1 Message Date
zzz
10aed35b08 0.8.1 2010-11-15 00:23:00 +00:00
zzz
355ca7b2f7 tweaks after review 2010-11-14 23:58:13 +00:00
m1xxy
2121b04f31 merge of '1e02b9123df580c44b0fa30918003bc8cf8030a4'
and 'c65ae88fa8b668ccd972d6a0bafe7843ea487285'
2010-11-14 19:25:06 +00:00
m1xxy
2420373389 language names consistency fix 2010-11-14 19:14:31 +00:00
hiddenz
235f6e0383 merge of '582904768901629443730b9763abb65e8ac8dd74'
and '8e94fe72b25ee4167620078c94890ca496fba9ad'
2010-11-14 18:40:58 +00:00
hiddenz
3f7d432f91 routerconsole: update russian translation
- Change translation of some terms:
  + тред -> поток
  + журнал -> лог
  + аптайм -> время работы
- use lowercase for second word where needed
- Reorder words where needed

These things was discussed on irc #ru
2010-11-14 18:38:23 +00:00
hiddenz
894e649be9 routerconsole: russian translation fixes 2010-11-14 17:35:52 +00:00
hiddenz
388767258a i2psnark: update russian translation 2010-11-14 16:27:27 +00:00
hiddenz
d6ea9cb0a4 i2ptunnel: update russian translation 2010-11-14 14:57:47 +00:00
m1xxy
9af33974eb merge of '9e5fa2ede2d44dd05b58b29796cb86a510628fa2'
and 'd0a4b4ea6faa776eb1e35049ffdc0fb0beee9135'
2010-11-13 23:00:10 +00:00
m1xxy
fdbfa00d96 fix missing </a> 2010-11-13 22:43:20 +00:00
hiddenz
e844cf25c2 routerconsole: update russian translation 2010-11-13 22:20:30 +00:00
HungryHobo
4df05f69b1 merge of '3aff7e5f43f96e1909cffca3b9c608bb6b02af53'
and '9dc9aae56898fbe4bb03c860f00dac9b8a5552b5'
2010-11-13 21:54:48 +00:00
m1xxy
c52693d2ac little translation tweaks in i2psnark 2010-11-13 20:02:04 +00:00
HungryHobo
8d2a75bc01 Add man pages for eepget and i2prouter 2010-11-13 17:58:05 +00:00
HungryHobo
5fe654e7e8 Abort if any command in the script exits with an error (lintian: maintainer-script-ignores-errors) 2010-11-13 17:55:34 +00:00
HungryHobo
cd741439d9 merge of '83f0017029b25b67b4d90694eba5ceefb9f006f9'
and 'ae9bcaf1a7c197b462162c4513161894de6c658a'
2010-11-13 17:25:25 +00:00
m1xxy
bdff919d3f only updating a flag on readme 2010-11-13 16:23:31 +00:00
zzz
f4b49f7425 change low mem error to warn 2010-11-13 12:06:16 +00:00
zzz
db7e4a273b static 2010-11-13 12:05:49 +00:00
m1xxy
42f6b9e24b merge of 'b6f941cc4c3eb51d9106dfdf35abdd7f3d1199af'
and 'ed834a4da30a6a913ab0145cd76519e5eaa969d2'
2010-11-13 10:53:30 +00:00
m1xxy
ad3ae84083 French translation Nachtrag 2010-11-13 10:53:14 +00:00
m1xxy
a4c9397db0 French translation of i2psnark done by Redzara. Thx, redzara\! 2010-11-13 09:56:43 +00:00
z3d
5380879aba I2PSnark: Update stopped.png 2010-11-13 08:50:46 +00:00
HungryHobo
eda1f8d640 merge of '89b2dc0430e50fd1ce78ab07cd3545aded81fee9'
and 'dcba57e8260ad530685ca665724566533964a7b4'
2010-11-13 04:14:13 +00:00
HungryHobo
88e98f0f67 Don't call the init script directly, use invoke-rc.d (lintian: maintainer-script-calls-init-script-directly) 2010-11-13 04:08:56 +00:00
m1xxy
2faa60ee59 update eepsite help 2010-11-13 02:43:35 +00:00
HungryHobo
b614d14037 merge of '4fff03e3acecbfb131a884b6c151967978058c49'
and '7ec0520d4bb67df2b9c378aab53bffbf8dcb222b'
2010-11-13 01:36:25 +00:00
m1xxy
d9bf826baf initialNews.xml fix; i2psnark translation tuning 2010-11-13 01:30:02 +00:00
HungryHobo
2152c5f6c9 Use a variable for /tmp to make lintian happy (possibly-insecure-handling-of-tmp-files-in-maintainer-script) 2010-11-13 00:39:55 +00:00
HungryHobo
0d23e37124 Add shebang to script 2010-11-13 00:30:11 +00:00
HungryHobo
fddf32a6ca * Stop service at runlevels 0 and 6 (lintian: init.d-script-possible-missing-stop)
* Add force-reload option, same as restart (lintian: init.d-script-does-not-implement-required-option)
2010-11-13 00:28:30 +00:00
HungryHobo
a07339e1ff Remove rc.d files in postrm, not in prerm (fixes lintian errors prerm-calls-updaterc.d and postrm-does-not-call-updaterc.d-for-init.d-script) 2010-11-13 00:03:13 +00:00
m1xxy
c5a6c5d412 merge of '963a4636469adb55ac3981048b32011865bb4faa'
and 'cdac59d49a839e82c626130a576b12a1297f981e'
2010-11-13 00:02:02 +00:00
m1xxy
7e17ac989b adding stub 2010-11-12 23:53:33 +00:00
HungryHobo
7b5e331038 Put a name and email in the Maintainer field 2010-11-12 23:28:25 +00:00
HungryHobo
ae101f6cad Reorganize the Debian directory structure to conform to their packaging policy. This brings the number of Lintian errors+warning
s down from 383 to 16.
2010-11-12 22:57:59 +00:00
z3d
98f559c9c0 I2PSnark: More width futzing. Please report any layout breakage (wrapping lines in main torrent table). 2010-11-12 19:08:47 +00:00
z3d
d368bb8ae0 I2PSnark: More width futzage. 2010-11-12 13:20:42 +00:00
z3d
33932eb373 I2PSnark: TorrentName width tuneup. 2010-11-12 12:58:17 +00:00
z3d
7d6e237183 merge of 'bc9f7e74001104c203687a91535b414228b5184b'
and 'f0ebb51ab350759843e67cdc74a8ec8158fe5ac6'
2010-11-12 12:28:52 +00:00
z3d
056fb5ea88 I2PSnark: Indentation cleanups. 2010-11-12 12:27:10 +00:00
m1xxy
92d013752a merge of 'c51af7655557d0a98ec7561a4f434c63d5f26f41'
and 'e42b35ff366e0c56916caaeec4a14f17ac95a0eb'
2010-11-12 09:03:51 +00:00
m1xxy
a9daf8fc8f bump bote to router console start page 2010-11-12 09:03:16 +00:00
HungryHobo
c3aa84f961 Run includedeb and include on each file individually, reprepro can't do multiple files 2010-11-12 05:09:06 +00:00
HungryHobo
b4524c67d5 Make separate i386 and amd64 packages, this fixes the arch-independent-package-contains-binary-or-object lintian error 2010-11-12 04:04:27 +00:00
m1xxy
11b69ee121 disapproval of revision '7c7c3832c57db0fee96000f6cf612d1443b0fc85' 2010-11-12 01:25:49 +00:00
m1xxy
be3330d84f bump bote to readme.hmtl 2010-11-12 00:49:05 +00:00
HungryHobo
9439477799 merge of '3643017f592675aa1170acb97e64ad78fbe9405c'
and 'ca29fd016d218f636d2cc844d46d6a25ca9ff5c6'
2010-11-11 22:40:14 +00:00
m1xxy
826efdf767 translation of dr|z3d's newly added stuff and more consitency fixes 2010-11-11 10:01:07 +00:00
z3d
7ef35e0284 I2PSnark: Do our level best to prevent stuff from wrapping and breaking the table layout; bump to -18rc. 2010-11-11 07:02:42 +00:00
z3d
0324bc4eec Bump to -17rc. 2010-11-11 06:50:15 +00:00
z3d
f157471ac1 I2PSnark: Increase min-width for status column to prevent column header from wrapping. 2010-11-11 06:49:14 +00:00
z3d
416e7825a8 I2PSnark: Remove thinspaces for download column. 2010-11-11 06:40:18 +00:00
z3d
6b12d26388 I2PSnark: Css tweak. 2010-11-11 06:32:16 +00:00
z3d
0adac224fb I2PSnark: Parent dir icon (up.png) tweak. 2010-11-11 06:28:41 +00:00
z3d
6935d7361a Bump to -16rc. 2010-11-11 06:15:53 +00:00
z3d
05409bae6e I2PSnark: Revert the regression, hopefully cunningly sidestepping conflicts. 2010-11-11 06:12:25 +00:00
z3d
283e915514 merge of '9ef5f8dbdf741e0d3f6f88061efff16e14d9182a'
and 'b44b28fa2d4279996e0adbc143968ec132faed8d'
2010-11-11 05:20:18 +00:00
z3d
676d84a081 I2PSnark: CSS whitespace/tab cleanups. 2010-11-11 03:58:20 +00:00
z3d
9f6e6cd54d I2PSnark: Add details_nolink.png icon for trackers that don't work with infohash extraction.
Mousever should provide minimal info, eg: tracker id.
2010-11-11 02:43:07 +00:00
z3d
dc51d694db Bump to -15rc. 2010-11-11 01:34:29 +00:00
z3d
0f63158f50 I2PSnark: Main torrent table tidyups and tweaks. 2010-11-11 01:33:56 +00:00
z3d
903d27ec0d Bump to -14rc. 2010-11-11 01:01:45 +00:00
z3d
5d9ed45cbd I2PSnark: Tweak details.png 2010-11-11 00:59:23 +00:00
z3d
7c0ef0ab80 I2PSnark: Tidyups. 2010-11-10 22:15:13 +00:00
HungryHobo
bda00e18fe * Fix build dependencies for Debian
* Add dependency on libc6 which fixes the lintian warning missing-dependency-on-libc
2010-11-10 21:01:52 +00:00
z3d
49fb6c59d1 Bump to -13rc. 2010-11-10 21:00:49 +00:00
z3d
224aa5fd9c I2PSnark: File manager cleanups. 2010-11-10 20:56:37 +00:00
z3d
25e21ffb1e I2PSnark: Screenlog padding fix. 2010-11-10 18:15:15 +00:00
z3d
0165c6068a Bump to -12rc. 2010-11-10 17:59:27 +00:00
z3d
585339e0d4 I2PSnark: All the goodness from the disapproved branch + visual fixes. 2010-11-10 17:56:33 +00:00
z3d
83ae568d38 I2PSnark: Fix Rate tag. Spotted by mixxy. 2010-11-10 14:53:15 +00:00
z3d
b323408cee merge of '285a9a021659672b12861eea3c150d47b5025275'
and 'a90a0715f156a732cf039bd2df9bbc3d90e82693'
2010-11-10 14:37:57 +00:00
z3d
71707bf0c0 disapproval of revision 'ffe706fb236d2cd14241d22dc6e6203964f8bc31' 2010-11-10 14:37:39 +00:00
m1xxy
7db5340159 merge of '96b28bcad599dea550230cc8cba4d7bce7f5fa68'
and 'a396094617a5124882fc16e11466375fcc4f3047'
2010-11-10 14:11:45 +00:00
m1xxy
dee2f2431c cinsistency fix 2010-11-10 14:09:26 +00:00
m1xxy
0b0fa04210 merge of '3dfa2ea9f44e204ca76d700e01ae09cda54c6b6a'
and 'a90a0715f156a732cf039bd2df9bbc3d90e82693'
2010-11-10 13:41:59 +00:00
m1xxy
18374fe426 German translation cleanups 2010-11-10 13:29:33 +00:00
HungryHobo
ab432e14ee Fail if repository cannot be created 2010-11-09 22:19:32 +00:00
HungryHobo
5d9a7b9452 Add changelog to .deb 2010-11-09 21:34:44 +00:00
HungryHobo
e9af7406c6 Update changelog 2010-11-09 21:30:32 +00:00
zzz
20e2e20212 * I2CP: Fix NPE caused by null session options (seen in i2pbote) 2010-11-08 16:13:43 +00:00
HungryHobo
7897df5544 Improve the Debian copyright file, see http://lists.debian.org/debian-legal/2003/12/msg00194.html 2010-11-08 03:23:30 +00:00
HungryHobo
0e9f0a741e Print destination in b64 2010-11-08 03:23:19 +00:00
zzz
31ff9b2747 update javadoc links and titles 2010-11-07 20:25:29 +00:00
zzz
dcd915457b minor javadoc fix 2010-11-07 20:23:45 +00:00
zzz
454a5c5286 explicit merge of '14597ede957582a9ca29df867f1565479c64888b'
and '6c0d71283dd65aea1fe1baad14ca57855808dad8'
2010-11-07 20:22:44 +00:00
m1xxy
168a4ca6f9 minor translation corrections #3 2010-11-07 00:48:22 +00:00
z3d
6e48ecb9ce I2PSnark: Fix syntax errors; tweak css. 2010-11-06 14:21:22 +00:00
zzz
959e57e755 RIP crstrack 2010-11-06 13:26:57 +00:00
HungryHobo
c2349662e7 Minor things 2010-11-06 05:40:24 +00:00
HungryHobo
43c7cc0893 Auto download jetty in the debian and debian-source targets 2010-11-06 05:38:00 +00:00
HungryHobo
d64a2b0306 * Add debianrepo target
* Change the debian target to build binary and source, add a debian-binary target
2010-11-06 04:51:11 +00:00
m1xxy
50aca88438 corrections of translation, mainly capitalization, ß and white spaces, some grammar fixes 2010-11-05 10:30:22 +00:00
HungryHobo
be5bd43194 Debian package: Fix purge with no prior remove (rev. 9a8fca24502aa8933793f2bad48e327596a2c0d4 only fixed remove, then purge) 2010-11-05 07:03:45 +00:00
m1xxy
8894aa7d38 minor translation corrections #2 2010-11-04 23:29:45 +00:00
m1xxy
092d29fe56 minor translation corrections 2010-11-04 08:55:25 +00:00
HungryHobo
8593931171 If the working directory contains only a plugins/ subdir, initialize it like it is empty 2010-11-04 06:49:12 +00:00
HungryHobo
77e0cb94d3 merge of '01966a37ff4e50e48ab6eeb9d215baa8b75fc46d'
and '85cbdd70a9896ae9b2257bfe8f25f045b1cd0b2d'
2010-11-04 04:24:23 +00:00
zzz
2b2c3cf118 snark tweaks 2010-11-03 22:21:10 +00:00
zzz
be308a0444 merge of '398a24f487b61ef778a2e849660e953ef7e43b39'
and '598d00efae4c9b675b64fd626bc2eab2b921e0c5'
2010-11-03 16:04:14 +00:00
z3d
9b39f02ce5 I2PSnark: Relocate errant "." 2010-11-02 14:07:25 +00:00
z3d
7109061ee0 merge of '4dfe5728ed4951d32f89e2fddbdcdfc3b4755cad'
and '62005c74e58b5fdbaf4659ffb65392ecfbd8bc0a'
2010-11-02 13:49:03 +00:00
z3d
f71dd25b3c I2PSnark: Relocate a pesky \n. 2010-11-02 13:48:11 +00:00
z3d
012fbe3a45 I2PSnark: Relocate </code> to its rightful place. 2010-11-02 13:22:48 +00:00
HungryHobo
853f941d88 merge of '598d00efae4c9b675b64fd626bc2eab2b921e0c5'
and 'd38686d88680521e54d7bcb8be24e21d252eb946'
2010-11-02 04:00:43 +00:00
HungryHobo
c03abb50d3 merge of '8c4c57f191c33a31bc69564888c9851f9042438c'
and '9c5d0b4cdfa76234e6ac9fbfd0ce753748104f47'
2010-11-02 03:51:00 +00:00
HungryHobo
94bc3c3503 merge of '1da5a6b3f2f42d9ddbe6b0a64e3c27313d61d86a'
and '5784df5facdf6e194dc3c052b2527a8c63c96c0f'
2010-11-02 03:49:06 +00:00
HungryHobo
252473d7cf merge of '5784df5facdf6e194dc3c052b2527a8c63c96c0f'
and '9c5d0b4cdfa76234e6ac9fbfd0ce753748104f47'
2010-11-01 22:09:52 +00:00
z3d
6eb8cbfacc I2PSnark: CSS refinements. 2010-11-01 22:08:05 +00:00
zzz
ddc86b54c7 fix snark rates 3x too low 2010-11-01 22:04:10 +00:00
zzz
3678aa157e * i2psnark:
- Limit number of parallel requests of a single piece when in the end game
      - Shorten and weight the speed tracker so the display is more
        reflective of current speed
2010-11-01 14:35:01 +00:00
z3d
4d7a77d318 I2PSnark: Bug fix. 2010-11-01 14:33:10 +00:00
zzz
8d13bcbac0 discourage b32 2010-11-01 14:30:57 +00:00
zzz
2f54ec61bd logging tweak 2010-11-01 14:30:24 +00:00
HungryHobo
af541662f3 Add get-orig-source rule as required by Ubuntu, see https://wiki.ubuntu.com/UbuntuDevelopment/CodeReviews#NewPackage 2010-10-31 21:13:53 +00:00
HungryHobo
3e2c530281 Fix error message with dpkg --purge 2010-10-31 19:54:49 +00:00
HungryHobo
ff5b7950f1 Debian package:
* Make eepget, i2prouter, and i2psvc world-executable
 * Auto-start I2P after installation
2010-10-31 19:52:28 +00:00
HungryHobo
148ce25af7 Print an error if /etc/init.d/i2p is run as non-root so Ubuntu users aren't asked for a non-existing root password 2010-10-31 19:48:41 +00:00
HungryHobo
56ef384595 Make /usr/bin/eepget and /usr/bin/i2prouter symlinks 2010-10-31 19:44:33 +00:00
HungryHobo
ea24f3ba6d Fix dependencies for Ubuntu 2010-10-31 19:41:55 +00:00
zzz
ba4f6608e4 update nbsp comment 2010-10-31 14:52:21 +00:00
zzz
07aa07981d * logs.jsp: Add message if wrapper log not found
(ticket #103)
2010-10-31 14:52:09 +00:00
zzz
0afabbd609 Add synch to fix race causing AIOOBE
http://forum.i2p/viewtopic.php?t=5061
2010-10-31 14:36:56 +00:00
zzz
2ea3f9b9bb parse log limit with current locale (ticket 118) 2010-10-31 14:33:31 +00:00
z3d
35a8c703a7 I2PSnark: Unitalicize remaining download amount. 2010-10-30 20:24:24 +00:00
z3d
d0855ee892 I2PSnark: Status icon updates. 2010-10-30 19:32:46 +00:00
z3d
e95b41511a I2PSnark: Add status icons, refine css. 2010-10-30 16:34:04 +00:00
zzz
30a5c4907b -6; history for this head 2010-10-30 15:50:03 +00:00
zzz
f170baab3f - Delay during StopAll so we don't close the tunnel before the
stopped announces go out and reopen it
- Logging tweaks
2010-10-30 15:30:14 +00:00
zzz
643687472a - Only add wanted pieces to wanted list at startup
- Make sure lastRequest is null when it should be
- Logging tweaks
2010-10-30 15:28:29 +00:00
zzz
c76058efc3 send &compact=1 to keep opentracker happy 2010-10-30 14:17:09 +00:00
zzz
502cf72653 fix nbsp screwing up POST 2010-10-30 00:38:08 +00:00
zzz
9baa6e7bc8 update requests after changing priorities 2010-10-29 20:31:07 +00:00
zzz
7efb0fa7ed * i2psnark:
- Priority mapping bugfix
      - Close files as we go when creating/checking
        so we don't run out of file descriptors
2010-10-29 17:32:05 +00:00
zzz
571ad83e03 use nbsp in formatSize2() 2010-10-27 14:22:53 +00:00
zzz
983e7683fd * i2psnark:
- Don't stay interested if we run out of pieces
        to request (thanks sponge)
      - Enhance debug mode to show requests
2010-10-27 13:29:27 +00:00
zzz
b9af4a8cf0 avoid rare transport NPE at startup 2010-10-27 13:25:13 +00:00
complication
f239d4f350 * Tiny readability fix: separate value and unit with a space. 2010-10-26 23:38:01 +00:00
z3d
4d77f62e38 I2PSnark: Fix alignment issue in file viewer filesize column. 2010-10-25 14:35:51 +00:00
zzz
ac3e6e27dc add note 2010-10-24 16:57:38 +00:00
zzz
4f9c442d55 fix disconnect race NPE 2010-10-24 16:56:43 +00:00
zzz
adab0cc3d3 * NTCP: Catch a race after stop() 2010-10-24 16:55:29 +00:00
zzz
b1f1725506 * Router: Set permissions on wrapper.log when not called by RouterLaunch 2010-10-24 16:52:41 +00:00
zzz
4bb902a8b9 * FileUtil: Make it easier to compile without Pack200, or with
Apache Harmony's Pack200, add unzip to main()
2010-10-24 16:49:20 +00:00
zzz
ed399a07d8 systray short doc and main() 2010-10-24 16:16:46 +00:00
z3d
4db38b9ba5 I2PSnark: Fix some showstopping whitespace issues. 2010-10-22 21:18:09 +00:00
z3d
22934545eb I2PSnark: Nuke the old copy of our snark theme in /themes/console/snark 2010-10-22 17:18:38 +00:00
z3d
7fe6b35359 I2PSnark: Tabs into spaces exercise. Release the kraken! 2010-10-22 16:49:07 +00:00
z3d
cfd2ad9a1c LICENSE.txt: Attribute I2PSnark's "Man with hat over face" graphic. 2010-10-22 16:33:30 +00:00
z3d
74a30aeee4 I2PSnark: Render unto Caesar what is due unto Caesar, namely some fixed tags. Enjoy! 2010-10-22 16:08:58 +00:00
z3d
1bff62e3c7 I2PSnark: Relocate theme to /themes/snark/ubergine/; update build.xml 2010-10-22 09:43:16 +00:00
z3d
31032cd794 merge of '42f7898ab54db310e16aa6fbedb1b078afe0ae18'
and '9d4166108eac930384ccb9c5859eede93f4d63ed'
2010-10-22 09:11:09 +00:00
z3d
8ccad29353 I2PSnark: Fix minor tag issue; add missing navbar bg graphic. 2010-10-22 09:01:29 +00:00
z3d
7ff873bbc9 merge of '6cf2d1b2af6daa4fffc59fede3407d3e10c09095'
and '9afc46edd20c72064eb24b5c1f6a4a8540e35799'
2010-10-22 08:25:44 +00:00
z3d
a55a464694 I2Psnark: Ensure our css uses the new path to our theme resources. 2010-10-22 08:17:49 +00:00
z3d
c14760c294 I2PSnark: Unbutcher tags; relocate our snark theme to /themes/snark; more css updates. 2010-10-22 08:14:51 +00:00
sponge
e6bf1af982 Sanity and some fixs for slackware package 2010-10-22 02:43:17 +00:00
sponge
3998ce311f Fix rc.i2p for slackware package 2010-10-22 02:26:13 +00:00
mathiasdm
e6c45ae5f8 Added package files for router. 2010-10-20 16:01:18 +00:00
mathiasdm
e8abe14395 Fixed susimail javadoc errors. 2010-10-20 15:55:28 +00:00
zzz
466128c179 * replaceAll() -> replace() when not using regex
* ampersand escaping (lots more to do)
2010-10-19 14:39:29 +00:00
zzz
8c7a39f00a * JobImpl: Deprecate getAddedBy() and addedToQueue()
to reduce LogManager records
2010-10-19 14:33:11 +00:00
echelon
1400c4d4d0 added plurals to fr, de and nl po file 2010-10-18 08:28:15 +00:00
zzz
24dd78394b priority persistence 2010-10-15 17:25:45 +00:00
zzz
9afff4f80a * i2psnark: Add file priority feature;
Use context random for shuffle; other cleanups
2010-10-15 13:48:36 +00:00
zzz
1aba324481 * I2PSocketEepGet: Set connect delay to save a RTT, will
speed announces in i2psnark
2010-10-15 13:41:56 +00:00
mathiasdm
3daa6b964d -Added package-file for time.
-Modified susi javadoc to remove more warnings (and non-javadoc '@see' to base class).
2010-10-14 16:05:06 +00:00
mathiasdm
8cda5104e3 - Added package doc for crypto and net.i2p
- Got rid of some susimail javadoc warnings
2010-10-14 06:19:19 +00:00
z3d
8db45ffaa1 merge of '01c6aeb6ee46c7795e83553f40e16b5bdae08aac'
and '56ee4b01df5de86f0fdc98cdc4ed1197104584b5'
2010-10-13 16:07:35 +00:00
z3d
b41e714a1b merge of '0738aeef8a1d4e9ca82dc5ba0077d83a57c47f81'
and '9625ea3e96d57df74bc62018bf64230a22c49ce0'
2010-10-13 16:07:33 +00:00
z3d
6cd645b34b I2PSnark: Tighten up navbar, color tweaks. 2010-10-13 16:03:41 +00:00
zzz
772c1d4fb8 explicit merge of '33c6e246dc934cddc886b50df2570c0caf122701'
and '4ef1d99f924ee431587d6f85241540e031fecbc1'
        to branch 'i2p.i2p'


Explicit merge from test4.
1.6 JDK now required to build.
1.5 JRE still OK to run I2P.

    * configlogging.jsp:
      - Add easy way to add an override
      - Make file size specifier more flexible
    * Console:
      - Sort RouterAddress options on netdb.jsp and peers.jsp
      - Remove unused web-*.xml file from war
    * Crypto:
      - Convert all ArrayList caching to LBQs in YKGenerator,
        HMACGenerator, and AESKeyCache.
      - Change DSAEngine params from Hash to new SHA1Hash, since
        these were really 20 byte hashes, not 32 byte Hashes.
      - Add stats to track YKGenerator caching success
      - Fix YKGenerator precalculation to be much more useful by
        increasing the cache size and dramatically shortening the delay
      - Option cleanups
      - YKGenerator cleanups
      - Mark HMAC256Generator unused
    * EepGet: Reset length variable on redirect
    * Files: Change permissions to 600/700 for all written files/directories.
      Now requires Java 1.6 to build, but only 1.5+ to run.
      (requires 1.6 to set permissiomns)
    * GeoIP: Fix locking bug causing lookups to stop
    * Hash: Throw IAE if data length is not 32 bytes,
      now that DSAEngine abuse is gone
    * HTTPResponseOutputStream:
      - More caching
      - Stats cleanup
      - Max header length check
      - Catch OOM
      - Initializer cleanup
      - Javadoc
    * I2CP:
      - Add new option i2cp.messageReliability=none, which prevents the
        router from sending MessageStatusMessages back in reply to an
        outbound SendMessageMessage. Since the streaming lib always ignored
        the MSMs anyway, make it the default for streaming.
        This will reduce the I2CP traffic significantly.
        MSM handling now avoided, but it is still fairly broken, see
        comments in I2PSessionImpl2.
      - Cleanups to replace method calls with fields
      - More cleanups, javadoc, rate reduction
    * i2psnark:
      - Compact response format
      - Add link to finished torrent in message box
      - Don't let one bad torrent prevent others from
        starting or stopping
      - Sort peers by completion %
      - Add some missing mime types to web.xml
      - shouldLog() cleanup
    * i2ptunnel:
      - Now that streaming flush() is fixed, use it in IRCClient, and
        for initial data in I2PTunnel runner, to avoid the 250 ms
        passive flush delay
      - Add hostname DSA signature field, to be used for addkey forms.
        Experimental, may be commented out later.
      - More header blocking (thanks telecomix!)
      - Remove unused web-*.xml file from war
    * Installer: Add startup hint for non-x86
    * Javadoc updates all over the place
    * LogConsoleBuffer: Java 5
    * Naming:
      - Increase cache size and expiration time
      - Add clearCache() method
      - Don't use EepGet or Exec for b32
      - Javadoc updates
    * NetDB:
      - Expire unreachable routers quickly, even if they don't have introducers,
        so we don't have old data on routers that ran out of introducers.
      - Fix rare NPEs at shutdown
    * NTCP:
      - Workaround for a rare 100% CPU bug in EventPumper
      - Cleanups
    * Streaming:
      - Make flush() block less, by waiting only for "accept" into the
        streaming queue rather than "completion" (i.e. ACK from the far end).
        This prevents complete stalls when flushing, and should help performance
        of apps that use flush(), like i2psnark (and SAM?).
        close() still does a flush that waits for completion, as i2ptunnel
        doesn't like a fast return from close().
      - cleanups
    * SusiDNS:
      - Remove unused web-*.xml file from war
    * TransportManager: Convert _transports from a List to a CHM
      to prevent a rare concurrent exception
    * Tunnels:
      - Don't use peers < 0.7.9 for tunnels due to the old
        message corruption bugs
      - Javadoc
      - Cleanups
    * UDP:
      - Beginnings of destroy message support
      - Try to avoid running out of introducers by relaxing selection criteria
        and increasing minimum number of potential introducers
      - Avoid rare AIOOBE
      - PacketBuilder refactor
      - Make most classes package private
      - Comments
      - Logging cleanup
      - Comment out a main()
2010-10-12 20:26:42 +00:00
HungryHobo
5a782cca4d Add HungryHobo as a signer 2010-10-12 19:30:46 +00:00
zzz
647b8f7fa1 default tweak 2010-10-11 15:18:17 +00:00
zzz
798bdf32c1 * Streaming:
- Make flush() block less, by waiting only for "accept" into the
        streaming queue rather than "completion" (i.e. ACK from the far end).
        This prevents complete window stalls when flushing, and should help performance
        of apps that use flush(), like i2psnark (and SAM?).
        close() still does a flush that waits for completion, as i2ptunnel
        doesn't like a fast return from close().
      - flush/close javadocs and comments
    * i2ptunnel:
      - Now that streaming flush() is fixed, use it in IRCClient, and
        for initial data in I2PTunnelRunner, to avoid the 250 ms
        passive flush delay
2010-10-11 15:17:35 +00:00
zzz
fbc20da606 more header blocking 2010-10-11 15:14:55 +00:00
sponge
0820b2c13f Bump version, add history 2010-10-10 14:36:11 +00:00
sponge
5f2361fe7c merge of '4ef1d99f924ee431587d6f85241540e031fecbc1'
and '56c6ae6a06651a05025a2e4f76ba35985a8ff372'
2010-10-10 14:32:35 +00:00
sponge
6e6142a91f Fulfill Request for name lookup feature. 2010-10-10 14:31:56 +00:00
zzz
500f6cf896 use context field 2010-10-07 18:42:30 +00:00
zzz
a23ea5e5f1 * configlogging.jsp:
- Add easy way to add an override
      - Make file size specifier more flexible
2010-10-07 18:39:03 +00:00
zzz
86a7d68f08 one more mime type 2010-10-07 15:14:07 +00:00
zzz
373fce2988 change perms on append too 2010-10-07 15:13:54 +00:00
zzz
8ac5d5d5fc add some missing mime types 2010-10-06 15:03:33 +00:00
zzz
3841e92d53 remove unused web-*.xml files from wars 2010-10-06 14:25:27 +00:00
walking
e5f53ed5e9 revise and fix 2010-10-06 13:07:34 +00:00
zzz
5ef9d46d0b dont sort in debug mode 2010-10-06 02:18:52 +00:00
zzz
5389ee056a sort snark peers by completion % 2010-10-06 02:05:26 +00:00
zzz
e2b7f93d11 fixup 2010-10-06 01:27:15 +00:00
zzz
09d1eb17d4 reset eepget length variable after a redirect 2010-10-06 01:11:21 +00:00
zzz
895c9a33a9 pluck build.xml javadoc changes from main branch 2010-10-05 14:52:44 +00:00
zzz
ab91d35331 comment 2010-10-05 13:15:39 +00:00
zzz
2d601099f3 propagate from branch 'i2p.i2p.zzz.test' (head 128a31611abc6a88e58133f3bf6a577fe6dd5b1c)
to branch 'i2p.i2p.zzz.test4' (head fa9a871892517271eb2531b433fe80a2a713be9c)
2010-10-05 13:06:16 +00:00
zzz
48ccf85e97 try again to fix the i2ptunnel nonce problem 2010-10-05 00:08:59 +00:00
zzz
6cf7bc7985 * i2ptunnel:
- Add hostname DSA signature field, to be used for addkey forms.
        Experimental, may be commented out later.
2010-10-02 17:20:39 +00:00
zzz
3d9b6061ce * NetDB:
- Expire unreachable routers quickly, even if they don't have introducers,
        so we don't have old data on routers that ran out of introducers.
      - Fix rare NPEs at shutdown
2010-10-02 17:07:37 +00:00
zzz
042cde2952 * UDP:
- Try to avoid running out of introducers by relaxing selection criteria
        and increasing minimum number of potential introducers
2010-10-02 17:04:52 +00:00
zzz
3b2aa946af * I2CP:
- Add new option i2cp.messageReliability=none, which prevents the
        router from sending MessageStatusMessages back in reply to an
        outbound SendMessageMessage. Since the streaming lib always ignored
        the MSMs anyway, make it the default for streaming.
        This will reduce the I2CP traffic significantly.
        MSM handling now avoided, but it is still fairly broken, see
        comments in I2PSessionImpl2.
      - Cleanups, javadoc, rate reduction
2010-10-02 16:56:02 +00:00
zzz
a687180d98 * TransportManager: Convert _transports from a List to a CHM
to prevent a rare concurrent exception
2010-10-02 16:30:07 +00:00
zzz
b1fd835f56 update irc description 2010-10-02 15:55:46 +00:00
zzz
53847dc3ad Sort RouterAddress options on peers.jsp and netdb.jsp 2010-10-02 15:51:48 +00:00
zzz
ec0c678cc9 * i2psnark:
- Add link to finished torrent in message box
      - Don't let one bad torrent prevent others from
        starting or stopping
2010-10-02 15:43:56 +00:00
zzz
b83184e895 initializer cleanup 2010-10-02 15:16:07 +00:00
zzz
f0f1a6f529 initializer cleanups, reduce rates, javadoc 2010-10-02 15:15:03 +00:00
zzz
333f80680e * UDP:
- Avoid rare AIOOBE
      - Comments
      - Logging cleanup
      - Comment out a main()
2010-10-02 15:11:41 +00:00
zzz
3489512a54 client cleanups 2010-10-02 15:07:35 +00:00
zzz
6100c799b7 LogConsoleBuffer cleanup 2010-10-02 15:03:20 +00:00
zzz
4a96e88118 * Hash: Throw IAE if data length is not 32 bytes,
now that DSAEngine abuse is gone
2010-10-02 15:00:30 +00:00
zzz
ed4c09b456 * Tunnels:
- Don't use peers < 0.7.9 for tunnels due to the old
        message corruption bugs
      - Javadoc
      - Cleanups
2010-10-02 14:56:45 +00:00
zzz
939dcee537 * GeoIP: Fix locking bug causing lookups to stop 2010-10-02 14:48:50 +00:00
zzz
7424fdd623 javadoc 2010-10-02 14:45:13 +00:00
zzz
4456048e79 * HTTPResponseOutputStream
- More caching
      - Stats cleanup
      - Max header length check
      - Catch OOM
      - Initializer cleanup
      - Javadoc
2010-10-02 14:43:40 +00:00
zzz
4c31c70298 Startup hint in installer for non-x86 2010-10-02 14:28:27 +00:00
zzz
c10a4f51ba I2CP: cleanups to replace method calls with fields 2010-10-02 14:27:01 +00:00
zzz
53dd0c7655 * Crypto:
- Convert all ArrayList caching to LBQs in YKGenerator,
        HMACGenerator, and AESKeyCache.
      - Change DSAEngine params from Hash to new SHA1Hash, since
        these were really 20 byte hashes, not 32 byte Hashes.
      - Add stats to track YKGenerator caching success
      - Fix YKGenerator precalculation to be much more useful by
        increasing the cache size and dramatically shortening the delay
      - Option cleanups
      - YKGenerator cleanups
      - Mark HMAC256Generator unused
2010-10-02 14:23:56 +00:00
zzz
6f449aa4f6 Naming:
- Increase cache size and expiration time
  - Add clearCache() method
  - Don't use EepGet or Exec for b32
  - Javadoc updates
2010-10-02 14:07:46 +00:00
zzz
171e3abe34 cleanups 2010-10-02 14:02:41 +00:00
zzz
2bffeea7eb comment out main 2010-10-02 14:01:38 +00:00
z3d
90288202e5 I2PSnark: Include missing add.png, spotted by xyz123. Bump to -3. 2010-10-02 00:36:31 +00:00
z3d
a4d24c61ba I2PSnark: Tweak the size of our writeable fields in add/create sections for better visual coherence. 2010-09-29 02:09:05 +00:00
z3d
3075593767 I2PSnark: Activity icons refresh. 2010-09-27 06:34:54 +00:00
z3d
8ab134ffe5 I2PSnark: Positional CSS tweaks 'n fiddles. 2010-09-27 06:05:02 +00:00
z3d
4800e73a4a I2PSnark: Add buttons for start/stop/delete torrents. 2010-09-27 05:04:05 +00:00
z3d
3bd97646a9 I2PSnark: Add favicon to file browser page; version bump to 0.8-02. 2010-09-23 04:56:43 +00:00
z3d
059e4176a1 I2PSnark: Rationalize file browser layout. 2010-09-23 02:43:05 +00:00
z3d
57b627fb71 I2PSnark: Add some icons to our file manager columns. 2010-09-22 21:18:57 +00:00
z3d
5281862932 I2PSnark: Kludge to fix extraneous space under message log on config page. 2010-09-20 21:07:27 +00:00
z3d
0fe2313754 I2PSnark: Configuration section tweaks. 2010-09-20 18:41:49 +00:00
z3d
f62dfb0abf I2PSnark: Invert show/hide peer icon functionality, tooltip change to "toggle peers"; fix alignment of "No torrents loaded" message with new css class; Replace brackets on Totals with &raquo;. 2010-09-20 11:26:28 +00:00
z3d
7507282886 I2PSnark: css tidyup. 2010-09-20 10:21:38 +00:00
z3d
9db5dd36b9 I2PSnark: alt tags, display filelength tweak. 2010-09-19 20:23:46 +00:00
z3d
9ce54d803f I2PSnark: show/hide peer icons. 2010-09-19 17:05:11 +00:00
z3d
7e7d36f0d6 I2PSnark: Table column header positional tweakery. 2010-09-19 15:43:57 +00:00
z3d
82323cd806 I2PSnark: Add icons for status and torrent columns. 2010-09-19 14:48:44 +00:00
z3d
511182f148 I2PSnark: status display tweakage. 2010-09-19 04:40:48 +00:00
z3d
e9b1db7ac7 I2PSnark: Update image references to point to our new snark theme directory. 2010-09-19 03:51:40 +00:00
z3d
9795334f12 build.xml: ensure we copy snark's directory, and remove the file copy for snark.css 2010-09-19 03:36:41 +00:00
z3d
321d88e795 I2PSnark: Add icons to relevant parts of the UI; rejigging of UI to minimise space wastage; create new snark directory in console/themes/ .. snark dir will need to be ignored when router scans directory for theme dirs. 2010-09-19 03:20:43 +00:00
z3d
99d2e2d0d0 I2PSnark: Fix alignment issue with snark_add.png 2010-09-18 16:36:29 +00:00
z3d
3fb1fbe1b3 I2PSnark: space savings! 2010-09-18 16:19:51 +00:00
z3d
d4f3304397 I2PSnark: Tweaks 'n fiddles. 2010-09-18 08:55:52 +00:00
z3d
4865373b4f I2PSnark: UI/theme tweaks. 2010-09-18 07:10:43 +00:00
z3d
5378b0ad56 I2PSnark: Transition from gray to puce. 2010-09-18 06:28:42 +00:00
z3d
7de357df98 Version bump. 2010-09-17 23:03:19 +00:00
z3d
27808012d0 I2PSnark: Reduced label lengths in preparation for icon substitution and tooltip; more colorification; Opera kludges. 2010-09-17 22:59:22 +00:00
z3d
dc22949b47 I2PSnark: more css polish; now with more color! 2010-09-17 16:02:15 +00:00
z3d
3d7ad215d9 I2PSnark: CSS Spit 'n polish. 2010-09-17 13:55:47 +00:00
z3d
67994d7e99 I2PSnark: snark.css fontsize tweaks. 2010-09-17 08:27:02 +00:00
z3d
deab6b40e0 I2PSnark: Fix text alignment issues. 2010-09-17 08:00:09 +00:00
z3d
0205fa6385 I2PSnark: snark.css finessing. 2010-09-17 07:27:21 +00:00
z3d
69b3343f45 Can't remember what. css stuff. 2010-09-16 23:33:24 +00:00
z3d
9c5b8419a5 I2PSnark: Add favicon. 2010-09-16 17:38:01 +00:00
z3d
fedf6d7537 I2PSnark css edits: log text visibility. 2010-09-16 16:49:27 +00:00
z3d
21306dbf5d merge of '1e79fc27bda464359d20795eaa33ed2ad61c9741'
and '7c6c62e901e75230e3a39e578f8fcbcf4cd2dd00'
2010-09-16 02:34:08 +00:00
z3d
9b69f2266a I2PSnark "faze to gray" theme: graphics and css futzing. 2010-09-16 02:32:07 +00:00
zzz
161f86b6bb improve and sort javadoc titles, put classes in the right places, add susi* 2010-09-15 15:25:32 +00:00
z3d
7f24dc5f03 Cross-browser tweaks to snark.css 2010-09-15 04:03:48 +00:00
z3d
6423c92b84 merge of '5e59656352811b3ccce9a2817417de1065ee9641'
and '8110890364bb45accd3016e90611f626e305b10e'
2010-09-15 01:50:30 +00:00
z3d
f7ea958961 Update history.txt to reflect Snark theme change. 2010-09-15 01:45:17 +00:00
z3d
8262048edc New default I2PSnark theme: faze to gray. 2010-09-15 01:39:38 +00:00
forget
73d956462f Fixed: recoded to UTF-8, cyrillic and chinese labels repaired. 2010-09-07 03:25:48 +00:00
forget
db0bc1a618 Fixed: missing links to the new Swedish help page. 2010-09-07 03:24:28 +00:00
zzz
91bcf947df * Javadocs
* Base64: comment out some unused methods
* Remove huge whitespace in CryptoConstants
* ElGamalAESEngine:
  - Reduce rates
  - Check number of tags earlier
2010-08-30 17:51:49 +00:00
z3d
c035ef6eb7 merge of '87f2562a0893b175a9b369e97b8413726f61935a'
and 'b1416986cd60fc129af81122324997fe0584472d'
2010-08-22 23:00:52 +00:00
z3d
4f31691c8a Add Swedish translation for eepsite help and update other help pages accordingly. Thanks to olleolleolle. 2010-08-20 22:51:58 +00:00
zzz
2244142bd8 javadoc, comment out some main()s 2010-08-14 18:22:46 +00:00
zzz
4323036992 javadocs 2010-08-10 16:17:09 +00:00
mathiasdm
8eeabe4409 merge of '85a542c53d910dffbf34cdcefb8a2faeee96adc4'
and 'c92f2bcd662936f16d539ea5e98b0d4496556384'
2010-08-08 10:01:51 +00:00
mathiasdm
6add722a25 Javadoc fix - thanks, duck! 2010-08-08 10:01:35 +00:00
mathiasdm
87abc1d6b4 CryptoConstants update from draft to RFC. 2010-07-31 12:49:38 +00:00
duck
6ddac9a478 Fix typo (trac #32) 2010-07-30 08:54:21 +00:00
echelon
38169b6d70 small fixes to _de 2010-07-26 12:08:17 +00:00
zzz
8cc561775b 0.8 2010-07-12 14:25:21 +00:00
zzz
0634154b28 final compact response format 2010-07-11 14:45:12 +00:00
duck
c08f79f71e Unfuzzy susidns translation, typo fixes for eepsite help. (thx _4get) 2010-07-10 11:49:40 +00:00
duck
7532276a00 Dutch eepsite help page 2010-07-10 11:04:30 +00:00
duck
ee29074a30 Dutch proxy translations, we missed a couple. 2010-07-10 09:06:26 +00:00
zzz
870ace55e2 version bump just to add -rc 2010-07-09 17:46:38 +00:00
zzz
05ac2594b6 more shouldLog() 2010-07-09 17:40:59 +00:00
zzz
8353b623da SSU PacketBuilder: Refactor header generation, add destroy msg support 2010-07-09 16:34:54 +00:00
zzz
c19af4dbcf i2psnark:
- Rework PeerID class so it depends only on peer desthash, since
    peer ID is not available with compact format. Implement deferred
    lookup of destination.
  - Implement compact tracker requests and response handling
    (may not be the final format)
  - Fix Peer hashCode()
  - Java 5
2010-07-09 16:32:31 +00:00
duck
ad7447f8ae merge of '6471243b39d38669b029124571adc47ad6417db4'
and 'a24bf3a898b6310d05bf2ee9ce99b3a52f067205'
2010-07-09 14:04:25 +00:00
duck
4f827a5b1d Dutch help page 2010-07-09 14:02:55 +00:00
zzz
be75455b84 More i2ptunnel error propagation fixes - key file - thx echelon 2010-07-08 18:45:30 +00:00
duck
96d3f67436 Dutch translation for RouterConsole sidebar labels 2010-07-08 14:41:56 +00:00
echelon
906bce637a new strings, corrections in german translation 2010-07-08 08:25:17 +00:00
forget
3c0d0dfeee Russian translation updated (help & faq link, local identity link) 2010-07-07 20:30:05 +00:00
duck
2ca5802e4d Include logo in updater now that it is themeable. (thanks RN!) 2010-07-07 19:49:07 +00:00
duck
f4b06e586e RouterConsole: Add Help & FAQ link, minor label improvements. 2010-07-07 19:04:30 +00:00
zzz
525806d776 merge of '798de678af324027c003163c81c1b6169a487992'
and 'a75a75901ecc2b8caa1b97cd0693f491063826ba'
2010-07-07 13:36:52 +00:00
zzz
01ef6baa53 beginnings of SSU destroy msg handling 2010-07-07 13:30:04 +00:00
zzz
ed04747517 snark css fix for Opera 10.60 thx i2pn00b http://forum.i2p/viewtopic.php?t=4712 2010-07-07 13:28:27 +00:00
duck
e13d336f2f Dutch translation of proxy error pages 2010-07-07 13:21:50 +00:00
zzz
5accdd24fc RIP p2i.mine.nu 2010-07-06 23:05:24 +00:00
duck
5c61c28772 Dutch news 2010-07-06 20:09:26 +00:00
zzz
3a767d84df concurrentify with LBQ 2010-07-06 17:14:57 +00:00
zzz
d04ce7a2b7 launch browser sooner 2010-07-06 17:14:41 +00:00
zzz
a1524241cb Set permissions on directories and files when they are created 2010-07-06 15:22:48 +00:00
duck
b312fdeac1 susidns: Dutch translation (thanks do monkeybrains) 2010-07-05 23:07:19 +00:00
privateer
30c8cf7b96 merge of 'c6af0acc022d4fc8e24488a86ab869d7cb561f57'
and 'fafee42899e7efa42942bc451a888bf77be69ac9'
2010-07-05 16:39:47 +00:00
zzz
50bda941ad make most classes package local; stub out a session destroy message; javadoc 2010-07-05 16:03:13 +00:00
zzz
fc6306575d new classes, requires Java 1.6 to build 2010-07-05 16:01:50 +00:00
privateer
c43ca7de87 - removed one useless line of code 2010-07-05 15:34:39 +00:00
privateer
826951536b - anged user agent for outproxy from Wget/1.11.4 to Firefox 3.6.6 on WinXP to avoid getting blocked as a crawler 2010-07-05 14:35:22 +00:00
zzz
5f52edf831 * I2PTunnelIRCClient: Filter PART messages like we do for QUIT 2010-07-05 14:21:38 +00:00
zzz
29bc53d618 * i2psnark: Fix transition to end game 2010-07-05 14:20:34 +00:00
zzz
378c855902 cleanup 2010-07-05 14:20:02 +00:00
duck
546a588aa5 I2PTunnel & I2PSnark: Dutch translation (thanks to monkeybrains) 2010-07-05 13:37:36 +00:00
duck
6e517c4a19 RouterConsole: Fix typos in Dutch translation 2010-07-04 23:03:02 +00:00
duck
30d3f52f30 RouterConsole: Dutch translation (thanks to monkeybrains) 2010-07-04 13:13:45 +00:00
zzz
5dee6cb3d5 * I2PTunnel: More error propagation fixes 2010-07-03 13:59:46 +00:00
zzz
2a96c9a145 static 2010-07-03 13:58:59 +00:00
zzz
6435514e0d * I2PTunnelHTTPClient: Don't use BufferedReader 2010-07-03 13:41:24 +00:00
zzz
cd7a41924d cleanup 2010-07-03 13:40:27 +00:00
zzz
b9452546c5 fix ant distclean poupdate 2010-07-03 13:39:25 +00:00
zzz
4fa89d5e86 javadoc 2010-07-03 13:38:13 +00:00
zzz
63ece7e1aa cleanup 2010-07-03 13:37:52 +00:00
walking
4808055054 merge of '02b40376f4c34b45e4f77deb70bd24bdef34f867'
and '2365aee6776961ebaa1ca862ffa21e0457ece0a6'
2010-07-02 05:45:46 +00:00
zzz
115016e75e add trac.i2p2.i2p (linked from logs.jsp) 2010-07-01 12:36:09 +00:00
walking
ee09bfac66 translation fix 2010-07-01 11:09:15 +00:00
zzz
530a3fcd10 * I2PTunnel: Don't start a tunnel if no valid destinations;
cleanups, logging, and error propagation fixes
2010-06-30 23:37:25 +00:00
zzz
0010229363 unused icon 2010-06-30 23:30:50 +00:00
zzz
d241afcbd8 * EventDispatcher: Minor cleanups and comments 2010-06-30 23:29:31 +00:00
zzz
615257831c * Transport: Fix NTCP address generation when host is specified but port is auto 2010-06-30 23:28:44 +00:00
zzz
b9b737f4ce propagate from branch 'i2p.i2p' (head 08b1e0356e38567d4632bdc0269506b5d89f7a7c)
to branch 'i2p.i2p.zzz.test' (head 181daec1a6229c188282645875162287879cbbc6)
2010-06-30 22:29:33 +00:00
sponge
36a032d249 25%-50% cpu savings in BOB. The remainder of the fix is in streaming lib,
which aparently keeps running and does not sleep according to profiling.
2010-06-29 19:06:39 +00:00
zzz
726079e0bb CapacityCalculator cleanup and comments - no changes to formula 2010-06-29 13:40:26 +00:00
zzz
66421858e7 formatSize cleanups 2010-06-29 02:32:08 +00:00
zzz
df7b3dd861 * Scale prng.buffers based on max memory, reduce default from 16 to 9 2010-06-29 02:30:40 +00:00
zzz
22ea79a4ff * Jetty: Disable TRACE and OPTIONS in console and eepsite 2010-06-29 02:29:42 +00:00
zzz
2025fe7c20 * SOCKS: Better HTTP error message 2010-06-29 02:27:10 +00:00
zzz
a11c529557 * I2PTunnel: Add default HTTPS outproxy 2010-06-29 02:25:29 +00:00
zzz
edaa2fba16 * RouterInfo: Add main() to dump RI files 2010-06-29 02:23:57 +00:00
duck
110f01a55b I2P logo in routerconsole sidebar is now themed. 2010-06-27 17:04:51 +00:00
forget
ada39a970e Russian translation updated (i2psnark startup delay option) 2010-06-26 21:20:04 +00:00
zzz
8c2641703c - Move connection profile and delay connect to advanced config section
- Add persistent client key support to SOCKS IRC
2010-06-26 04:11:02 +00:00
zzz
9fcb07250d explicitly set shared client for POP (defaults true anyway) 2010-06-26 04:06:32 +00:00
zzz
47f39d0766 stripHTML on form params 2010-06-26 04:05:30 +00:00
zzz
bcba5af8a9 static 2010-06-26 04:04:01 +00:00
zzz
aec1b3aeef * jbigi, jcpuid: Suppress log messages when not in router context 2010-06-26 04:03:33 +00:00
zzz
a979ed770d * logs.jsp: Add more JVM version info so we can distinguish OpenJDK from Sun 2010-06-26 04:01:58 +00:00
zzz
5485568764 * jetty.xml: Add info on how to configure for following symlinks 2010-06-26 04:01:13 +00:00
zzz
6f3597cc83 fix display of interactive setting 2010-06-26 04:00:18 +00:00
zzz
1202d09966 * FileUtil: Try to handle lack of unpack200 support more gracefully
* Update: Select old update URL if no unpack200 available
2010-06-16 13:29:41 +00:00
zzz
266eb8307c sort countries using collator for locale for current language 2010-06-16 13:23:21 +00:00
zzz
8843cc2948 cleanups 2010-06-16 13:22:35 +00:00
echelon
2c4acce0f3 finally i2ptunnel messages_de 2010-06-15 12:13:49 +00:00
echelon
87beb2ea1a updated susidns messages_de, fix kbit/kbyte in i2psnark messages_de 2010-06-15 09:27:59 +00:00
echelon
9c5b7760ba mentioned path of jetty to be put in 2010-06-14 17:29:23 +00:00
echelon
6964786552 plural fixes. hope thats all 2010-06-14 10:06:28 +00:00
echelon
d755756ee5 routerconsole messages_de.po updated 2010-06-14 09:52:27 +00:00
echelon
fbc970e4a7 updates i2psnark messages_de 2010-06-14 07:38:58 +00:00
zzz
364b905790 UDP fix and comments 2010-06-13 16:42:24 +00:00
zzz
34a1085604 use a different user agent for outproxy traffic 2010-06-13 16:04:28 +00:00
zzz
c460ac8ade * Console: Add some divs for languages to news and readmes 2010-06-13 16:02:33 +00:00
zzz
49a09f61a2 * i2psnark:
- Move config to separate page
      - Icon tweaks
2010-06-13 16:01:11 +00:00
zzz
08b4563f49 zh fix 2010-06-13 15:54:01 +00:00
echelon
026f62f183 i2ptunnel .de 2010-06-13 12:44:17 +00:00
echelon
2307ac5a22 SusiDNS .de and i2psnark .de translations 2010-06-13 12:41:15 +00:00
echelon
2b186421a7 change more 2010-06-13 11:51:22 +00:00
echelon-transport
1dc471e07e router console messages_de.po 100 percent done 2010-06-13 11:48:59 +00:00
dev
db1fb7ccf7 minor style change 2010-06-12 11:06:24 +00:00
dev
e5071a3b7c update history 2010-06-12 11:03:56 +00:00
dev
e6bfe0c10b fixed possible race-condition and improved code style 2010-06-12 11:02:39 +00:00
dev
919a97d4c8 really fixed #49 now.. use Context->routerHash instead of calculating it everyt time 2010-06-09 12:43:48 +00:00
dev
61216b638d fixed #49: missing calculateHash() 2010-06-09 12:37:11 +00:00
dev
e065d2b01e merge of '8c5085970b330a592129aa2da5a473d318426bbb'
and 'f11c600b339d0742fb91a87df7322ec4b84eee4d'
2010-06-08 15:37:25 +00:00
zzz
746bad3c30 remove jetty fixes from release target 2010-06-07 12:57:10 +00:00
zzz
5bbd61b75c 0.7.14 2010-06-07 12:18:43 +00:00
zzz
27eb7e46d0 tweak 2 2010-06-06 20:38:19 +00:00
zzz
c20bef3731 tweaks after review 2010-06-06 20:36:54 +00:00
dev
d5aaff7f06 merge of '9ec612b8794a44b9337b7743afef8ccbb2fc904e'
and 'ec741e25082ea0a9d1fd530f613b2282edefc1d9'
2010-06-06 15:51:25 +00:00
dev
fc60768a66 prevent an NPE in case the connection is gone already(but that should not happen?) 2010-06-06 15:49:29 +00:00
zzz
8ef1dac95b propagate from branch 'i2p.i2p' (head 45d9fab2e437a2acf99febfab1c50b28c342c694)
to branch 'i2p.i2p.zzz.test' (head 946c3527d4481d3dcf0b8ab163d1e248673c1733)
2010-06-05 10:32:27 +00:00
zzz
2024fb1b65 * Netdb:
- Use new receivedAsReply flag in LeaseSet to mark
        those received as response to a query
      - Mark which methods in FloodfillPeerSelector may return
        our own hash
      - Redefine selectNearest() so it may return our own hash,
        so it can be used for closeness measurement
      - Redefine findNearestRouters() to return Hashes
        instead of RouterInfos
      - Fix LeaseSet response decisions for floodfills, based
        on partial keyspace and closeness measurements
      - List only count of published leasesets in netdb
2010-06-05 01:10:56 +00:00
zzz
617ca79b8f conn throttler fix when only total configured 2010-06-05 01:07:29 +00:00
privateer
5081755d0b - integration of dynamicly configurable startup delay of i2psnark
- i2psnark webfrontent configuration of startup delay
- default startup delay 3 minutes
- new config variable in i2psnark.config: i2psnark.startupDelay
2010-06-04 23:50:13 +00:00
zzz
7bfb5b1bf4 readme cleanup 2010-06-04 12:18:57 +00:00
walking
8d73529fa4 po revise 2010-06-04 03:46:52 +00:00
dev
a19d04d3ba merge of '4002ce96746459cd6ab6f91f16795bdbe3165644'
and 'db4aaff4718328041f29e6166333139f845406cd'
2010-06-03 23:13:35 +00:00
dev
a9c7748a52 minor code style updates to ntcp EventPumper 2010-06-03 23:13:13 +00:00
zzz
41e4e952b7 * Update: Fix multiple updates after manually
starting update - caused by refreshing summary bar
      (thx 'backup'!)
2010-06-03 16:53:55 +00:00
zzz
c0b0b5e4c5 Add min delay after startup before fetching news 2010-06-03 16:51:37 +00:00
forget
e424479e7e peers.jsp:
Show definitions panel if any transport is enabled (was: only for UDP). 
  Use div.wideload for the whole page (was: only for transports and broken if only one of them enabled).
2010-06-03 08:35:14 +00:00
dream
a8804f3093 merge of 'bdef8183da2c97dd55e2c2fad915537640e0f404'
and 'f908793c77bb4bd3d5fa3dd71bed704f32404fd0'
2010-06-03 07:21:52 +00:00
dream
6479a24bb7 merge of '0bd9edccbe59dc0c8dddee2b45cde1af0f8551f2'
and '779311c9e2df158049abc2e0f56e4e9fcb071142'
2010-06-03 06:27:12 +00:00
dream
8b372ad306 Fixed build.sh
jbigi's build.sh had a number of failed assumptions as per where I2P and JAVA_HOME were which needed to be removed and a warning put in their place. A better solution would be to have some way to search for JAVA_HOME and I2P in common locations, but at least this solution works if you do it manually:

I2P=~i2p JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.20 sh build.sh dynamic

thank zzz for prodding me to do this
2010-06-03 03:35:46 +00:00
forget
86791a2f1b Russian translation updated (descriptions for the stats that are graphed by default) 2010-06-03 03:22:35 +00:00
zzz
7cf0aad388 * UDP: Fix a bug from a blank i2np.udp.host config
causing frequent RouterInfo updates and incorrect
      addition of introducers, caused by config.jsp handling
2010-06-02 18:20:13 +00:00
zzz
c5ea51beec * graphs.jsp: Tag some more 2010-06-02 18:16:43 +00:00
zzz
7cc8e51d73 * Update: Change default update URLs to .su2 for pack200 2010-06-02 18:13:45 +00:00
zzz
75ba58d68c * Translation: Set xgettext add-comments option 2010-06-02 18:12:46 +00:00
zzz
cd35b219db * i2psnark:
- More listing fixes (more thanks to 'backup')
      - Start end game a little sooner
2010-06-01 22:19:10 +00:00
zzz
4a863f8ce7 comment 2010-06-01 14:02:21 +00:00
zzz
24264548a6 * Installer: Disable pack200 in updater again, doesn't work
on Java 1.5
    * Remove jetty from updater - it's been in for a few
      releases, and i2psnark now has its own listHTML method
2010-06-01 14:01:21 +00:00
zzz
f9e4b1a56b snark css tweak 2010-06-01 13:57:39 +00:00
zzz
13b54b864e * i2psnark:
- More listing fixes
      - Revert choker change
      thx 'backup' !
2010-06-01 13:56:53 +00:00
walking
05d45fe945 po update 2010-05-29 07:18:56 +00:00
forget
2781f6035a Russian translation updated for ngettext (plural forms) strings 2010-05-27 17:59:57 +00:00
zzz
dc3378d084 * Translate: Add GNU ngettext (plurals) support 2010-05-27 00:38:32 +00:00
zzz
9132e94143 * i2psnark: Listing fixes and cleanups; icons on front page; tweak bw choker again 2010-05-26 14:28:46 +00:00
forget
b61e2aa73c Russian translation updated 2010-05-26 04:37:28 +00:00
forget
7fdbae3b0f Tagged "bytes remaining" 2010-05-26 04:37:03 +00:00
dev
4dc6fc3b5d merge of '20f5a25a77de641ddf49c4d47d4ede923b59bfa3'
and '7dfc6bc466e7b6ee3212af949a08c51d4e3dd3db'
2010-05-25 19:08:31 +00:00
dev
618275b1f9 merge of '13c351b9c26b147632b40df8c0e8d9ca7d2d4485'
and 'b281a23e2f1719a388abed362ec3653f63e6769b'
2010-05-25 19:07:13 +00:00
dev
7a1111d845 updated history 2010-05-25 19:06:15 +00:00
zzz
3af356840e -11 2010-05-25 18:31:09 +00:00
zzz
911a278926 snark listing icons and cleanups 2010-05-25 13:08:34 +00:00
dev
014063700f merge of '82b66240733c560b038d4874d1630bf59f5fbe1a'
and 'd6f8e674646687b5efb03d09b6cdca57c6bd8f50'
2010-05-23 19:52:49 +00:00
dev
f7c0db0454 -10 2010-05-23 19:52:06 +00:00
zzz
a534d25d82 -10 2010-05-23 19:18:50 +00:00
zzz
bcf3e4a2d3 merge of '200dbdfc1dba31eb7abc6bb3403ac77cc9072c94'
and '56425d32b819bb74fe3abb999e7e3763814533ac'
2010-05-23 19:17:50 +00:00
dev
0cdfbd9803 merge of '01deefdd2f5a2b8f21fd3e97d1a6bd0dd66fecab'
and '1a75d8e703883bde472616a9def0b27bb64b7815'
2010-05-23 18:08:26 +00:00
dev
a3e5654d86 merge of '03e8a3d066ce112bb4ddaa98c0387dfefde94a0e'
and '751ff97c62634ee13a8f8baf3d7947e373d5368a'
2010-05-23 17:05:15 +00:00
dev
2f9364db2b fixed a major bug in the datagram dissector, improved performance a little bit and added a utility method to get the already calculated hash of the payload 2010-05-23 17:04:37 +00:00
zzz
5d7c9ebf82 * i2psnark:
- Choke slower when at bandwidth limit
      - Fix completion % for small files
      - Use Random from context
2010-05-23 16:18:10 +00:00
zzz
48da98d0e4 * NewsFetcher:
- Add backup URL
      - Change to 0 retries (was 2)
2010-05-23 16:15:37 +00:00
dev
55e994ac3c merge of '751ff97c62634ee13a8f8baf3d7947e373d5368a'
and 'ddc06f282f1b88e164c208509d818e3ed701143e'
2010-05-23 16:06:20 +00:00
dev
6d46a21f9f implemented WEBIRC support in the I2PTunnel IRC server 2010-05-23 16:04:22 +00:00
dream
fdc83484fd NTCP bind interface
Adding support for binding to a specific IP in the NTCP configuration. Uses new config option i2np.ntcp.bindAddress.
2010-05-22 16:50:39 +00:00
zzz
6786817fff -9 2010-05-21 17:34:30 +00:00
zzz
b77cd0db15 show completion status in listing 2010-05-21 15:07:34 +00:00
zzz
20bef76878 * i2psnark:
- Spiff up dir listings
      - Urlify some messages
      - Only go into end game at the end
      - Bye Bart Bye
2010-05-21 04:38:49 +00:00
zzz
7a30490482 more validation 2010-05-19 18:55:53 +00:00
zzz
3bc2e469cc remove unnecessaary initializers from constructors 2010-05-16 18:08:24 +00:00
zzz
d770d3c6da border-radius thx dr. 2010-05-16 17:11:40 +00:00
zzz
339a001592 never used 2010-05-16 13:16:05 +00:00
zzz
ace57a96a9 translate log priorities 2010-05-15 15:42:20 +00:00
zzz
2c26b8d422 * Hash: Move caching XOR methods only used by KBucket into netdb 2010-05-15 14:21:31 +00:00
zzz
e1eafa2394 * Eepsite: Set no-cache in redirecting page 2010-05-15 14:19:41 +00:00
zzz
39cb51c9eb snark css tweaks 2010-05-15 14:18:54 +00:00
zzz
fa5016ab04 javadoc fix 2010-05-15 14:17:54 +00:00
zzz
b134ef1a74 * Console:
- Tag text in graphs
      - Move SummaryRenderer to its own file
2010-05-15 14:17:17 +00:00
zzz
234dff888d Try to prevent ZipErrors after plugin update 2010-05-13 17:04:16 +00:00
zzz
a08c15a3ee leaseset debug tweak 2010-05-13 17:02:32 +00:00
zzz
cfa894e7b6 peer id tweak 2010-05-13 17:01:30 +00:00
zzz
d6c8e64575 throttle fix 2010-05-10 16:21:20 +00:00
zzz
dc91580e30 fixes from DataHelper.eq() deprecation 2010-05-10 15:58:53 +00:00
zzz
7ec1dd7a98 netdb.jsp leaseset debug 2010-05-10 15:22:10 +00:00
zzz
82f3f7506c * NetDB:
- Handle old and duplicate stores more efficiently
      - Have DataStore put() return success
2010-05-10 15:00:13 +00:00
zzz
e26df1c26b * LeaseSet: Add receivedAsReply() methods in preparation for
some netdb changes
2010-05-10 14:52:53 +00:00
zzz
aea77cf225 * NetDB: Move getDistance() to its own class 2010-05-10 14:50:55 +00:00
zzz
a1e3ef9c5c cleanup fail output on peers.jsp 2010-05-10 14:26:19 +00:00
zzz
7aece71342 cleanup 2010-05-10 14:24:47 +00:00
zzz
bdbde54f04 * Router: Add router.forceBandwidthClass advanced config for testing 2010-05-10 14:23:25 +00:00
zzz
157e035710 summary bar tweaks 2010-05-10 14:22:37 +00:00
zzz
97d9a3a4e5 show monthly bw estimate 2010-05-10 14:21:48 +00:00
zzz
cb7f111ade * UDP: To help limit connections, don't offer to introduce
when floodfill
2010-05-10 14:20:27 +00:00
zzz
35f670706a * TunnelPoolManager: Concurrent 2010-05-10 14:18:15 +00:00
zzz
3fac888fe5 * DataHelper: Deprecate inefficient eq() methods 2010-05-10 14:17:05 +00:00
zzz
d843646b4f * Streaming: Add support for connection throttling 2010-05-10 14:15:31 +00:00
zzz
c2b73d9fb5 * i2psnark:
- Add tunnel config dropdowns
      - Comment out old proxy stuff
2010-05-10 14:13:55 +00:00
sponge
9da95b8165 PluginStarter: If there is some delay, there may be a really good reason for it.
Loading a class would be one of them!
    So we do a quick check first, If it bombs out, we delay and try again.
    If it bombs after that, then we throw the ClassNotFoundException.
2010-05-10 07:27:34 +00:00
zzz
5bcd8efe14 2 transport test classes out 2010-05-06 13:21:30 +00:00
walking
027a1d748d merge of '19b2cad8459bddf9473031504b0f30aa3aad97e3'
and '5fc11615066ab7c27262a8670b7713405d25424c'
2010-05-06 04:15:34 +00:00
walking
6d6e012c19 adapt to the change in build.xml 2010-05-06 03:59:23 +00:00
zzz
a8db6b007f * Plugins:
- Set classpath for specific client only, not for the whole JVM
      - Use ConfigDir() not AppDir()
2010-05-05 19:34:03 +00:00
zzz
f3576e54c6 throw IllegalStateException rather than NPE if no context 2010-05-05 18:44:12 +00:00
zzz
0325f6c4d2 more isEmpty and a static 2010-05-05 18:43:33 +00:00
zzz
8225ce063a * Console: Print stack trace if exception on startup 2010-05-05 17:50:28 +00:00
zzz
c2c379c994 * i2psnark: Skip 'the' when sorting snarks 2010-05-05 17:45:52 +00:00
zzz
7344c2af47 * I2PTunnelHTTPClient: Reject 192.168.* 2010-05-05 17:34:24 +00:00
zzz
f484ea8c64 * EepGet: Limit max times to fail completely even if numRetries is higher 2010-05-05 17:27:20 +00:00
zzz
ac790492eb * build.xml: Create packed sud in release 2010-05-05 16:55:00 +00:00
zzz
9ac5fb4890 * RouterInfo: Clean up use of sortStructures() 2010-05-05 16:54:28 +00:00
zzz
2baee7413c * Replace size() <= 0 with isEmpty() everywhere, ditto > 0 -> !isEmpty() 2010-05-05 16:51:54 +00:00
walking
16bec08f09 merge of '03068a89c26b0986a8bf2b6f36cb478f565664eb'
and 'c3c31953c884c3aafb142e05c2dbef2809516d9c'
2010-05-03 16:44:06 +00:00
walking
afb3c76922 - rewrite portable targets
pkg-portable-clean
	preppkg-portable-win32-jbigi
	preppkg-portable-linux-jbigi
	preppkg-portable-basic
	preppkg-portable-win32
	pkg-portable-win32
- add windoz support to target pack200
2010-05-03 16:42:45 +00:00
z3d
2f526b35e8 merge of '77299d7d613df0c3d1308d1056facc243ef693bb'
and 'a088711b406a5c062940ebbdd1709aa891283d74'
2010-05-02 16:43:46 +00:00
walking
2dc32aa310 fix name "preppkg-linux-only" 2010-05-02 13:04:40 +00:00
zzz
10e669165a Fix plugin version check bug 2010-05-02 12:19:17 +00:00
zzz
b6cb90d731 * ByteCache:
- Add a per-cache stat
      - Limit each cache based on max memory
      - Disable in UDP MessageReceiver
      - Add clearAll() method to be called when under
        severe memory pressure; call from Router
2010-05-02 12:14:14 +00:00
zzz
949a8901fb comment out mains 2010-05-02 12:11:20 +00:00
walking
d608f450af return what is taken a way ;) 2010-05-02 11:30:31 +00:00
z3d
e0a1341901 Adjust dimensions of installer splash graphic: was 171x275, now 171x270. 2010-04-30 10:26:54 +00:00
z3d
2cfb03f17d New installer splash graphic. 2010-04-30 09:30:01 +00:00
z3d
4dd0f51da4 merge of '6b54027d89ac66a5b395118365de13f5ab61bcaf'
and 'b915692e91863a7122937dbd0bad366bf38a7dfc'
2010-04-30 09:26:43 +00:00
dev
d65a3e54a2 update checklist 2010-04-28 17:53:18 +00:00
walking
c212eacf19 - add new target: pkg-portable-win32 (must run buildSmall first)
- add configs/win batchfiles to installer/resources/portable

* currently only pkg-portable-win32 on win32 available
need linuxers to write target preppkg-portable-nix/pkg-portable-linux
and enable pkg-portable-win32 on linux (i doubt anyone need it ?)
shell scripts should goto installer/resources/portable/configs/linux/
2010-04-27 15:01:03 +00:00
zzz
46f341d782 peers.jsp: cleanup and tag 2010-04-27 12:55:37 +00:00
zzz
ab4ff5548d fix reseed tips links 2010-04-27 12:54:07 +00:00
zzz
d4713e1e6c every body needs some <body> 2010-04-27 12:53:16 +00:00
zzz
8a3a1466c9 * i2psnark: Serve downloaded files from the servlet rather
than with a file: link
2010-04-27 12:52:17 +00:00
zzz
a5af9dc973 * Jetty: Backport directory listing bugfix from jetty 6 2010-04-27 12:51:14 +00:00
zzz
049a083e42 0.7.13 2010-04-27 01:43:35 +00:00
zzz
9683a110d6 plugin cleanups 2010-04-23 16:28:14 +00:00
zzz
c44698f61a comments 2010-04-23 16:27:56 +00:00
zzz
106bccda0e log compress errors 2010-04-21 17:41:14 +00:00
zzz
b1aafa5aaf increase buf size for extraction 2010-04-21 17:06:54 +00:00
zzz
e2e43cd534 * EepGet: Don't convert a MalformedURLException into
an IOE so we recognize it when it's throuwn
2010-04-21 17:05:39 +00:00
zzz
43b4fe8300 * ReusableGZIPStreams:
- Concurrent
      - Workaround for Apache Harmony 5.0M13 Deflater bug
2010-04-21 17:04:53 +00:00
zzz
7c3e4fd947 reduce floodfill max conns slightly; fix clients start button 2010-04-18 23:06:04 +00:00
zzz
9916ef4d3d IRC links on readmes and initialNews 2010-04-18 19:57:42 +00:00
zzz
ad4da54bc4 I2PTunnelServer: Log incoming connections with net.i2p.i2ptunnel.I2PTunnelServer=INFO 2010-04-18 15:22:33 +00:00
sponge
2415c5a38b * BOB early session destroy to speed up tunnel tare-down. 2010-04-16 19:38:40 +00:00
HungryHobo
ecbc0a2a2d Show the start button when a plugin is not running, and the stop button when a plugin is running. 2010-04-16 03:58:48 +00:00
zzz
10d37a9be5 log tweaks 2010-04-15 18:16:00 +00:00
zzz
590d2e4639 Floodfills: Increase max to 100 (was 60) and min to 60 (was 45) 2010-04-15 18:14:21 +00:00
zzz
806a07acc5 Limit max length in readline() 2010-04-15 18:13:51 +00:00
zzz
8258cdd6cf Limit max header lines 2010-04-15 18:13:30 +00:00
sponge
2fcee6e87a I2PTunnelHTTPClient: Test for "http://:/" and output error page.
This avoids an ArrayIndexOutOfBoundsException, which can eventually
cause the eepproxy to stop functioning.
2010-04-15 06:38:35 +00:00
zzz
04efbc8819 propagate from branch 'i2p.i2p' (head 2c845f47f9323817088f27c61390558ad723b84a)
to branch 'i2p.i2p.zzz.test' (head 97a16a11a0fa27c0fa44df062573a51af938e068)
2010-04-14 14:05:39 +00:00
zzz
1fc288917a back to updater 2010-04-14 14:05:25 +00:00
zzz
27587e83c8 add test 2010-04-12 22:26:54 +00:00
zzz
a0d6741ff5 fix wrong prefix for startOnLoad in plugin webapps.config 2010-04-12 21:11:22 +00:00
zzz
63562ddd48 * i2ptunnel: Implement access lists for TCP servers.
Enter b32 or b64 hash or dest into list box, and
      check enable for whitelist. Uncheck enable and enter
      i2cp.enableBlackList=true in advanced i2cp options for
      blacklist. Todo: make black/whitelists radio buttons.
2010-04-12 19:18:21 +00:00
zzz
aac96b15b0 * configstats.jsp: Fix full stats checkbox default 2010-04-12 19:12:04 +00:00
zzz
0f502b4229 * LogManager: Concurrent 2010-04-12 19:10:11 +00:00
zzz
a916f970b1 * i2psnark: - Concurrent, limit, display, log tweaks 2010-04-12 19:07:53 +00:00
zzz
7f2d0acc3b merge of 'b12b7f42f59f400abd7032f3f2bffba289f3ec7a'
and 'b5a86744c2877d9d738a2fdd2b99970a0160e062'
2010-04-10 16:06:14 +00:00
zzz
8b6751f419 Streaming:
Fix the window size increment logic so it does it much more often.
The code increased the window size by MSS * MSS / N, like
in RFC 2581, but it did it only once every N,
so that was like MSS * MSS / N**2.
Now do it all the time, except for isolated packets like keepalives
that aren't using more than one message of the window.
Seems to speed up outbound significantly, without any
noticable increase in stream.sendsBeforeAck.
2010-04-10 15:42:08 +00:00
zzz
70e9cf5838 add comments about the null privkey bug 2010-04-10 15:41:42 +00:00
zzz
24020302fd cleanup 2010-04-10 15:29:16 +00:00
zzz
d7e2f39d25 * Startup:
- Don't die horribly if there is a router.info file
        but no router.keys file
        http://forum.i2p/viewtopic.php?t=4424
      - Log tweaks
2010-04-10 15:28:31 +00:00
zzz
89d0d7b266 Disconnect seeds that connect to a seed 2010-04-10 15:26:23 +00:00
zzz
e3c222b5c1 Lower per-torrent conn limits for large pieces 2010-04-10 15:25:57 +00:00
forget
a199015bc9 Russian translation updated (trac.i2p2.i2p link) 2010-04-08 09:57:32 +00:00
zzz
23617f7b30 dont set stats off, defaults to off anyway 2010-04-07 23:22:48 +00:00
zzz
f5f02236df toString() for logging 2010-04-07 23:21:45 +00:00
zzz
ad76bc378c * OCMOSJ:
- Increase min timeout
      - Logging tweaks
2010-04-07 23:20:42 +00:00
zzz
570d8d15af * Key Manager: Hopefully avoid some races at startup
http://forum.i2p/viewtopic.php?t=4424
2010-04-07 23:19:24 +00:00
zzz
e254c5f31a * Streaming:
- Detect and drop dup SYNs rather than create
        a duplicate connection - will hopefully fix
        "Received a syn with the wrong IDs"
      - Send reset for a SYN ACK with the wrong IDs
      - Don't send a reset to a null dest
      - Logging tweaks
      - Cleanups
2010-04-07 23:18:58 +00:00
zzz
2a92be5946 * Console:
- More HTML transitional fixes
      - Standardize on 'save' to the right of 'cancel'
2010-04-05 13:34:45 +00:00
zzz
caab860351 - Add tooltip support for plugin links
- Make target=_blank for plugin links
2010-04-05 13:22:16 +00:00
z3d
32861b7ce9 merge of '44418e8f7048de3ac06833176b607d55afc94bdd'
and '6cd2f8bb60720e3aeeb500d67b3f162f2831c3fa'
2010-04-05 12:26:28 +00:00
z3d
a08802c4b6 Fix the errant horizontal rule in the console news section (classic/midnight). 2010-04-04 11:32:28 +00:00
z3d
6b51be6fae Fix the errant horizontal rule issue in the console news section (classic/midnight). 2010-04-04 05:46:07 +00:00
zzz
5b5c975884 turned the knob the wrong way before 2010-04-02 13:10:08 +00:00
zzz
605dfec5e7 dont call exit 2010-03-31 18:33:40 +00:00
zzz
71aa0cfba7 * FloodfillPeerSelector: Adjust rankings to try to
improve LeaseSet lookups
2010-03-31 18:33:08 +00:00
zzz
55e45c4274 * HostsTxtNamingService: Don't load the whole hosts.txt
into memory for every lookup
2010-03-31 18:32:16 +00:00
zzz
8c880b2518 prep for a windows-only pkg 2010-03-29 21:21:56 +00:00
zzz
c43b16cfbb * configclients.jsp:
- Always show start button for webapps and plugins
    * configclients.jsp, configupdate.jsp:
      - Fix submission when entering CR in a text box
    * Plugins:
      - Stop all plugins at shutdown
      - Log tweaks
    * WebApps:
      - Remove the WAC after stopping it
      - Stop a WAC before starting it to prevent dups
2010-03-29 21:20:48 +00:00
zzz
394903a8f0 - Implement destroy() in i2psnark to prevent dups 2010-03-29 21:14:35 +00:00
zzz
e31c0636ab - Implement destroy() in addressbook to prevent dups 2010-03-29 21:13:45 +00:00
zzz
e9fe80f8e5 * HTTPResponseOutputStream: More static 2010-03-29 21:12:51 +00:00
zzz
7671550a9f * EepGet: Don't retry after a MalformedURLException 2010-03-29 21:12:04 +00:00
zzz
83d24fa90d -2 2010-03-25 20:26:28 +00:00
zzz
3e2956da3f * netdb.jsp: Tag transport properties 2010-03-25 20:25:03 +00:00
zzz
cf3fd01012 * Plugins: Remove final check and install console
messages after a while
2010-03-25 20:23:32 +00:00
zzz
319071c73b Add new reseed host
thx merd@mail.i2p
2010-03-25 19:09:30 +00:00
zzz
ab8d9bb79b * PrivateKeyFile: Add b32 output 2010-03-25 19:07:35 +00:00
zzz
25eaf8cad7 fix dup anchor 2010-03-25 19:06:47 +00:00
zzz
c8f97d9c73 * i2psnark:
- Send numwant=0 if we don't need peers
      - Report returned complete and incomplete counts
        if higher than peer count
      - Allow missing peer list
      - Log tweaks
2010-03-25 19:05:45 +00:00
zzz
d3f1fe1c30 * Console: Sort plugin links in summary bar 2010-03-25 19:04:45 +00:00
zzz
5fb01a01af history for prop, -1 2010-03-18 15:55:42 +00:00
zzz
617d1cd648 propagate from branch 'i2p.i2p.zzz.test' (head c295ab421dd719cfe0e273268b5b4e48505e4f61)
to branch 'i2p.i2p' (head 995914d8e049d9bb695fd25e4cf5be860cd4e487)
2010-03-18 15:49:03 +00:00
zzz
f672193fcf enable VTBM 2010-03-18 15:48:40 +00:00
zzz
d3c490e9d7 bold the rest of the update msg 2010-03-18 12:32:28 +00:00
zzz
2e8fd23f2b concurrent 2010-03-18 12:32:01 +00:00
zzz
3eef403b04 concurrent 2010-03-18 12:31:44 +00:00
zzz
f3b78fc82f post-release cost cleanup 2010-03-17 22:05:45 +00:00
zzz
80654b2732 Discard at IBGW based on router clock not system clock 2010-03-17 17:00:35 +00:00
zzz
05597ae914 disable i2ptunnel nonce checking if console password is set 2010-03-17 16:23:20 +00:00
zzz
0f1eb464e8 add reseed host thx mathiasdm 2010-03-17 16:22:11 +00:00
zzz
8745ffd42f * config.jsp: Set burst to +10% for 20s by default,
to fix bug where the burst stays high when limits
      are reduced.
2010-03-17 16:18:25 +00:00
zzz
db99e98658 display transport cost 2010-03-17 16:15:52 +00:00
zzz
9f1a663f63 typo fix thx duck 2010-03-16 13:52:57 +00:00
zzz
db0b3da446 snark up bw tracking tweak 2010-03-16 13:32:34 +00:00
zzz
5d22d41201 pack200 for installer (-3.3MB) 2010-03-16 12:38:07 +00:00
zzz
b397de1d54 link to trac 2010-03-16 12:37:32 +00:00
dev
4bda79b263 merge of '7e9ec9156e65514e00e0d9f82be002cf9aadac5f'
and '9df57c2abc8e859828f9edf80e9d104fd6bf6729'
2010-03-15 19:01:28 +00:00
dev
697a9dbd06 merge of '59ab6afe6ba2e217124fe55e8d854d0e04b965c4'
and '6cf70779bcd05bcf782d6d7bb8d131ce8d71426f'
2010-03-15 19:01:07 +00:00
dev
accaabcfde added c.netdb.i2p2.de to the reseed sites 2010-03-15 19:01:03 +00:00
zzz
5026cbdc8d 0.7.12 2010-03-15 18:03:46 +00:00
zzz
16a14d4ebd * Clients:
- Negative delay means run immediately and inline
      - Add methods to test class and run inline,
        to propagate errors to the console
      - Add javadoc for clients.config format
      - Use new methods for plugins
2010-03-15 16:19:19 +00:00
zzz
c151352910 cleanup 2010-03-15 16:15:23 +00:00
zzz
52e2aaa20d javadoc cleanup after review 2010-03-15 14:34:25 +00:00
zzz
9df87ba167 partial fix for i2ptunnel nonce troubles 2010-03-13 20:33:48 +00:00
zzz
b80f70fc54 dont yell so loud 2010-03-13 16:04:32 +00:00
zzz
939cdb019b log tweak 2010-03-13 15:00:47 +00:00
zzz
fde36fe238 flip backwards arraycopy args 2010-03-13 14:59:54 +00:00
forget
116be93160 Russian translation updated (snark file open error message, reseed messages, SOCKS IRC proxy) 2010-03-13 09:57:55 +00:00
zzz
40e820cabb * UDP:
- Big refactor of several classes for concurrent,
        elimination of several locks
      - Reduce max number of resent acks in a packet to
        lower overhead
      - Take incoming messages from the head of the queue,
        not sure why taking them from the tail "reduces latency"
      - Java 5 cleanup
2010-03-09 20:44:46 +00:00
zzz
d79387bd92 * TunnelGatewayPumper: Refactor for concurrent 2010-03-09 20:43:30 +00:00
zzz
05f2a62cbb * Job Queue:
- Replace some locks with concurrent
      - Change job ID to a long so it won't wrap
      - Remove some unused stats
      - Java 5 and debug cleanup
2010-03-09 17:32:29 +00:00
zzz
78a965dc90 * FIFOBandwidthRefiller:
- Replace global counters with atomics
      - Use lockless shortcut methods to grant
        requests if we can satisfy immediately
2010-03-09 17:10:18 +00:00
zzz
5b603d6627 cleanups and comments 2010-03-08 22:17:46 +00:00
zzz
e93d2046d3 Remove some unused stats 2010-03-08 22:15:42 +00:00
zzz
995871db8a more java 5 cleanups 2010-03-08 22:13:43 +00:00
zzz
501535f196 Java 5 cleanups 2010-03-08 22:07:52 +00:00
zzz
91e854e99c * Peer Manager:
- Replace some locks with concurrent
      - Switch back to fast version of getPeersByCapability()
      - Java 5 cleanup
2010-03-08 22:02:42 +00:00
zzz
9b05d8e774 * ByteCache:
- Remove some locks with concurrent
2010-03-08 21:32:14 +00:00
zzz
e70793c3bc propagate from branch 'i2p.i2p' (head b7a8a00272124eec0d149224af58bd144358c009)
to branch 'i2p.i2p.zzz.test' (head a4d67a357c36f4e94718bf237a7af96b8617a4a7)
2010-03-08 20:04:55 +00:00
zzz
abb2603bea one more unused class 2010-03-08 20:04:35 +00:00
HungryHobo
c91218be27 Add i2pbote.net to the list of reseed hosts 2010-03-08 05:14:26 +00:00
zzz
9eab44128a * Random: Remove and deprecate some old classses 2010-03-08 00:48:56 +00:00
zzz
f98101afa6 * i2psnark: Better track outgoing bandwidth by incrementing
counter before the blocking write
2010-03-08 00:45:08 +00:00
zzz
4fae7a8cb6 * Floodfills: Increase max to 60 (was 28) and min to 45 (was 20) 2010-03-08 00:44:40 +00:00
zzz
26cf1922db * Reseeder: Reduce max response size to 1MB (was 8MB) 2010-03-08 00:44:15 +00:00
neutron
c087b0695f An update of the network configuration page in the messages_fr.po file. 2010-03-06 13:22:49 +00:00
zzz
16930d2004 merge of '18a87911d2a41f5a1fa0f5019d9bcd7249731338'
and '1d260b764d0fde4b8df67bdb23320b85e6944721'
2010-03-05 15:56:57 +00:00
zzz
33939e7cfb translate country names on flag popups 2010-03-05 15:56:17 +00:00
zzz
e759ef5865 tag console reseed messages 2010-03-05 15:36:24 +00:00
zzz
2be1b1ece4 couple of tags 2010-03-05 15:27:32 +00:00
walking
1820a29aed translation update 2010-03-05 15:14:43 +00:00
zzz
ee9f85d53c rename getString() since it was getting tagged 2010-03-05 14:44:50 +00:00
zzz
afbb1dbe86 compile fix 2010-03-05 14:44:18 +00:00
zzz
9244bd6b0f * I2PSOCKSIRCTunnel:
- New, for filtering IRC client traffic when using SOCKS
    * I2PTunnelIRCClient:
      - Make filter classes static and public for use by SOCKS
      - Eliminate redundant case conversion
      - Pass ISON message through (jIRCii uses it for pings)
      - Switch back to StringBuffer since it's used by 2 threads
      - Set daemon on filter threads
    * SOCKS5Server:
      - Fix handling of multiple authentication methods
2010-03-05 14:04:32 +00:00
zzz
6bb4403207 updates after trying SDK 2.1 2010-03-05 13:48:26 +00:00
walking
24ebd503d4 susidns translation 2010-03-05 13:39:37 +00:00
forget
285a5eed35 Russian translation updated (job queue link, address helper conflict message) 2010-03-04 13:04:01 +00:00
zzz
26aebe6a0f * Console:
- Add link to jobs.jsp on configservice.jsp
      - Add plugin disableStop support
2010-03-02 22:54:32 +00:00
zzz
ca9f174171 * Context: Add boolean getProperty methods 2010-03-02 22:52:26 +00:00
zzz
ffbced22b3 * LoadClientAppsJob:
- Fix unquoted arg after quoted arg
      - Logging cleanup
2010-03-02 22:51:53 +00:00
zzz
45ca459ceb * HTTP Proxy:
- Fix address helper conflicts caused by last checkin
      - Use B32 instead of random hostname for conflict link
2010-03-02 22:50:46 +00:00
HungryHobo
5a539f0619 merge of '98497fef229d3e37922d4c09cb52e043b01647ee'
and 'de5aa1476c5d447deb031032dbfbc921114dfbd6'
2010-02-27 18:03:05 +00:00
HungryHobo
c6cef72cb7 Fix: webapps keep asking for the router console password even after the user entered it 2010-02-27 18:02:56 +00:00
zzz
8081d053cc Prevent UDP startup NPE http://zzz.i2p/topics/571 2010-02-27 14:38:52 +00:00
zzz
efdc8e5df0 * HTTP Proxy:
- Put B32 instead of B64 in Host: header, saves 450 bytes
      - Eliminate some redundant lookups
      - Fix http://i2p/b64/ and /eepproxy/site/ requests
      - Disallow a port specified for an i2p address
      - Cleanup and comments
2010-02-27 01:16:39 +00:00
zzz
b4911a2b2f support plugin themes 2010-02-26 16:58:01 +00:00
zzz
7b70210c9a * UDP Transport:
- Replace the unused-since-2006 TimedWeightedPriorityMessageQueue
        with DummyThrottle
      - Don't instantiate and start TWPMQ Cleaner and OutboundRefiller
        threads, part of priority queues unused since 0.6.1.11
      - Don't instantiate and start UDPFlooder, it is for testing only
2010-02-26 16:54:41 +00:00
zzz
e3353df8bb * NTCP Transport:
- Replace lists with concurrent queues in EventPumper
        and NTCPConnection to remove global locks
      - Java 5 cleanup
2010-02-26 16:52:09 +00:00
zzz
25285fc059 remove jobs link from summary bar 2010-02-26 16:47:41 +00:00
zzz
7720f71e44 * eepsite: Add some help to index.html 2010-02-26 16:46:12 +00:00
zzz
1657ac5357 * netdb: Fix NPE after OOM http://trac.i2p2.i2p/ticket/38 2010-02-26 16:45:34 +00:00
zzz
299214aa1d * i2psnark:
- Fix NPE after create file failure
      - Sanitize more characters in file names
2010-02-26 16:44:49 +00:00
forget
5fd4488e08 Russian translation updated (delete confirmation, non-i2p trackers warning) 2010-02-23 08:49:37 +00:00
zzz
87fcaf2651 * Unzip: Any files in the zip with a .jar.pack or .war.pack extension
will be transparently unpacked with unpack200. Savings is about 60%.
      Someday we will do this for suds, but we can do it for xpi2ps now.
    * build: Add updater200 target
2010-02-23 02:44:47 +00:00
zzz
f6b9cf6f21 * configclients.jsp:
- Add js delete confirm
      - Remove delete button for webapps
    * i2psnark:
      - Ignore a non-i2p tracker in a torrent rather than deleting
        the torrent, thus "converting" a torrent to in-netowrk use
        via the open trackers
      - Add js delete confirm
2010-02-22 18:17:11 +00:00
zzz
eae18e61b7 unhide plugins, fix d/l status display 2010-02-19 14:42:43 +00:00
zzz
96735f2543 make file box bigger 2010-02-19 14:40:57 +00:00
forget
54459d3b5c Russian translation updated (plugin support) 2010-02-18 21:16:15 +00:00
zzz
82444f9e7b move getConsoleServer() method 2010-02-18 16:33:47 +00:00
zzz
3d8365a473 * HTTP Proxy: Fix blank page instead of error page for eepsite unreachable 2010-02-18 16:32:44 +00:00
zzz
e2dc9715d2 * Transport:
- Fix recognition of IP change when not firewalled
      - Require consecutive identical results from two peers before changing IP
2010-02-18 16:31:57 +00:00
zzz
d4f1230b37 better error message when finding HTML instead of metainfo 2010-02-17 19:56:54 +00:00
zzz
7701693d37 * Plugins:
- Fix plugin start button
      - Change signer prop to match docs
      - Tweaks
2010-02-17 18:12:46 +00:00
zzz
b6704fce4e javadoc fix 2010-02-17 18:11:16 +00:00
zzz
39a68d4a2b slew tweak 2010-02-17 18:10:45 +00:00
zzz
94633899d7 CLI exit 1 on error for ease of use in scripts 2010-02-17 18:10:20 +00:00
zzz
c45bc1554f move to i2p.scripts 2010-02-17 18:08:54 +00:00
forget
789c8edc45 Russian translation updated (plugin support) 2010-02-15 20:53:49 +00:00
zzz
e0b44f43e3 history for 3 props, -1 2010-02-15 16:37:22 +00:00
zzz
b45069e377 propagate from branch 'i2p.i2p.zzz.VTBM' (head fb6ef5bc51e18536bc1611a483e9be804084e37b)
to branch 'i2p.i2p' (head c9f5d7378a6028393fe560739ec02f5f87f50f80)
2010-02-15 16:22:20 +00:00
zzz
c3a156ce4b propagate from branch 'i2p.i2p.zzz.plugin' (head fafcd8c8c41873b4d106a9e06504dd7b48109ad8)
to branch 'i2p.i2p' (head 7eafbe18b0a1e26f09b9488d374f5fed4c278a78)
2010-02-15 16:21:15 +00:00
zzz
ee5cc099ed propagate from branch 'i2p.i2p.zzz.test' (head 0914f799641c6ec04dbe40f325f8368403167885)
to branch 'i2p.i2p' (head f3d096929c21753a2117f93d7550b751b021c2a7)
2010-02-15 16:17:40 +00:00
zzz
f189587153 log tweak 2010-02-15 16:16:03 +00:00
zzz
a1fb5ef6ed verify that signing key name matches 2010-02-15 16:12:49 +00:00
zzz
8c2550c39a * Streaming: MessageOutputStream logging tweaks 2010-02-15 16:10:41 +00:00
zzz
1d3f0fe96c * Transport:
- Update addressses before publishing
      - Increment address cost if near capacity
      - Synchronize notifyReplaceAddress()
2010-02-15 04:08:02 +00:00
zzz
49a6cdbda6 - Clear the geoip negative cache periodically 2010-02-14 01:17:19 +00:00
zzz
2700028da7 * Transport: Adjust bids based on address cost
- More finals
2010-02-13 15:16:12 +00:00
zzz
4f70a7d0fe * Clock:
- getFramedAveragePeerClockSkew() now returns a long (ms);
        was a Long (s)
      - Implement NTP-style clock slewing so the clock is adjusted
        gradually
      - Implement clock strata so we prefer better clocks
      - Implement a timestamper in the transport so we will periodically
        update the clock even if NTP is not working
        This allows the router to converge the clock instead of simply
        hoping the first connected peer is correct.
      - Slow down NTP attempts after several consecutive failures
2010-02-13 01:20:23 +00:00
zzz
f265db4037 fix stop button; catch and log exceptions better 2010-02-11 21:41:54 +00:00
zzz
62308f26bc * Plugins:
- Fix classpath setting for webapps
      - Implement uninstall args in clients.config
2010-02-11 19:18:26 +00:00
zzz
cada9fae44 flush requests in I2PTunelRunner 2010-02-10 20:13:07 +00:00
zzz
949aea951e * Plugins:
- Hook up update/delete/check/save buttons
      - Implement delete
      - Hide unless router.enablePlugins=true
2010-02-10 19:09:35 +00:00
zzz
cfc49ab261 * Plugins:
- Check plugin key against all installed plugins
      - Reword some error messages
    * VersionComparator: add '-' and '_' as valid separators
      to better support plugin and java version checking
2010-02-10 15:35:00 +00:00
zzz
880f1866dc take version number off jrobin jar so we can overwrite if we upgrade 2010-02-10 12:06:30 +00:00
zzz
54171e4be2 ... and more 2010-02-08 23:37:31 +00:00
zzz
a820c01ba5 strip HTML from fields 2010-02-08 23:28:09 +00:00
zzz
9d1ae891bb check for mismatched versions 2010-02-08 22:50:30 +00:00
zzz
2df7247e83 fix start webapp, add stop webapp 2010-02-08 22:19:59 +00:00
zzz
a109ebef28 stop button 2010-02-08 20:57:30 +00:00
zzz
c0135b592d plugin stopper 2010-02-08 20:37:49 +00:00
zzz
b7a0aeea34 plugin buttons 2010-02-08 19:04:46 +00:00
zzz
66375e25c6 start of a plugin version checker 2010-02-08 18:45:53 +00:00
zzz
85482a67f5 plugin description on configclients 2010-02-08 16:15:23 +00:00
zzz
9012baf51e plugin links 2010-02-07 19:01:06 +00:00
zzz
3c8355790f load translation bundles in plugins 2010-02-07 18:18:31 +00:00
zzz
e9f1da85e4 classpath for plugins 2010-02-07 17:13:44 +00:00
zzz
58adccfd4a start of a plugin starter 2010-02-07 13:32:49 +00:00
zzz
040f3e016e move jrobin from routerconsole.jar to its own jar 2010-02-06 20:48:14 +00:00
zzz
505d5f5cae * Plugins: New plugin downloader/installer
* configclients.jsp: Use new WebAppStarter so webapps that are
      started later also get the temp dir, password, and classpath
      configuration just like if they were started at the beginning
    * configupdate.jsp: Delay after checking for update so the
      summary bar will have buttons.
2010-02-06 20:25:13 +00:00
zzz
f7780b6745 * TrustedUpdate:
- Allow method to check if we know about a key
      - Add method to extract without verifying
2010-02-06 18:47:08 +00:00
zzz
7a59d15e9c - Pull jstl.jar and standard.jar out of susidns.war (-300KB someday)
- Remove duplicate classes from i2psnark.war (100KB)
2010-02-06 18:44:29 +00:00
zzz
9b141bd9dd * Webapps: Allow additions to a webapp classpath. This will let us:
- Pull jstl.jar and standard.jar out of susidns.war
      - Remove 100KB of duplicate classes from i2psnark.war
      - Add classpaths for plugins
2010-02-06 18:40:55 +00:00
zzz
375118fe02 Refactor and tag update status messages 2010-02-05 21:12:10 +00:00
zzz
3aebe45a7d refactor the storage of signing keys 2010-02-05 19:19:33 +00:00
zzz
2f8b55ceda propagate from branch 'i2p.i2p' (head d84bac5f340fb1f9f4826a3326847a84cf32b1a1)
to branch 'i2p.i2p.zzz.test' (head c055e344e2d86aa417bb248bb0a6c54ba3b2f52d)
2010-02-05 00:31:33 +00:00
zzz
b77be20cc1 set up transport cost constants 2010-02-05 00:31:00 +00:00
zzz
b0502b1873 Fix several VTBM read/write bugs after testing 2010-02-03 14:16:05 +00:00
zzz
d7015cf2e6 disable sending VTBMs 2010-02-01 14:46:00 +00:00
zzz
5689fa8512 propagate from branch 'i2p.i2p' (head 2b1a99ea78270f80514ced3860a7d54cc3f2e309)
to branch 'i2p.i2p.zzz.VTBM' (head 155eea7b96fa5ce48faec385242e0b6eb232b0dd)
2010-02-01 14:39:16 +00:00
zzz
25e51a945c - Fix first hop expiration for Build Messages, was way too long
- Randomize Build Message expiration to make it harder to guess hop position
      - Save expired tunnel build configs for a while, so that we will still use the tunnel
        and update peer stats if the reply comes in late
      - Don't update our own profile for Tunnel Build Replies
2010-02-01 14:17:11 +00:00
zzz
839986db22 * I2NP: Add UnknownI2NPMessage so we can route unknown message types 2010-01-31 16:31:36 +00:00
zzz
56b3e6a993 * Tunnel Building:
- Add getRecordCount() to TunnelBuildMessage and TunnelBuildReplyMessage
        so they can be extended.
      - New I2NP Messages VariableTunnelBuildMessage and VariableTunnelBuildReplyMessage,
        which contain the number of request slots in them.
      - Convert all static assumptions of 8 slots to getRecordCount()
      - Use the new VTBM if all hops in the tunnel and the OBEP or IBGW of the reply tunnel
        support it, and the tunnel is 4 hops or shorter.
      - Reply to a VTBM with a VTBRM of the same size
      - Make BuildReplyHandler static
      - Convert the currentlyBuilding List to a ConcurrentHashMap to speed reply lookups
        and eliminate a global lock; don't put fallback tunnels in there
      - Add new tunnel.corruptBuildReply stat
      - Various cleanups and javadoc

    Tested as compatible with current network, new messages untested.
2010-01-29 19:22:10 +00:00
616 changed files with 39686 additions and 14740 deletions

View File

@@ -27,6 +27,7 @@ run I2P for the first time.
To run I2P explicitly:
(*nix): sh i2prouter start
(win*): I2P.exe
(Platforms unsupported by the wrapper - PPC, ARM, etc): sh runplain.sh
To stop the router (gracefully):
lynx http://localhost:7657/configservice.jsp ("Shutdown gracefully")

View File

@@ -2,6 +2,7 @@ I2P source installation instructions
Prerequisites to build from source:
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
The SDK must have Pack200 support (java.util.jar.Pack200)
Apache Ant 1.7.0 or higher
Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed
from the GNU gettext package http://www.gnu.org/software/gettext/

View File

@@ -64,6 +64,9 @@ Public domain except as listed below:
Copyright 2006 Gregory Rubin grrubin@gmail.com
See licenses/LICENSE-HashCash.txt
GettextResource from gettext v0.18:
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
See licenses/LICENSE-LGPLv2.1.txt
Router:
@@ -139,6 +142,7 @@ Applications:
I2PSnark:
Copyright (C) 2003 Mark J. Wielaard
See licenses/LICENSE-GPLv2.txt
Silk icons: See licenses/LICENSE-SilkIcons.txt
I2PTunnel:
(c) 2003 - 2004 mihi
@@ -176,6 +180,7 @@ Applications:
Router console:
Public domain.
Flag icons: public domain, courtesy mjames@gmail.com http://www.famfamfam.com/
Silk icons: See licenses/LICENSE-SilkIcons.txt
GeoIP Data:
Copyright (c) 2003 Direct Information Pvt. Ltd. All Rights Reserved.
@@ -231,3 +236,7 @@ distributions. See the source package for the additional license information.
SAM Python Library:
Public domain.
I2PSnark:
"Man with hat over face" graphic licensed under a Creative Commons 2.0 license.
Original photo by Florian Kuhlmann. http://www.flickr.com/photos/floriankuhlmann/3117758155

View File

@@ -1,5 +1,6 @@
Prerequisites to build from source:
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
The SDK must have Pack200 support (java.util.jar.Pack200)
Apache Ant 1.7.0 or higher
Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed
from the GNU gettext package http://www.gnu.org/software/gettext/

View File

@@ -2,15 +2,32 @@
# Start/stop i2p service.
i2p_start() {
/bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory start )"
# Check if router is up first!
/bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory status )" > /dev/null
if [ ! $? -eq 0 ] ; then {
# I2p is already running, so tell the user.
echo "I2P is already running..."
i2p_status
}
else
{
# Just in-case there are leftover junk in /tmp...
rm -Rf `grep /tmp/hsperfdata_root/* -le i2p` /tmp/i2p-*.tmp /tmp/router.ping
# Now that all junk is cleaned up, start.
/bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory start )"
}
fi
}
i2p_stop() {
/bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory stop )"
rm -Rf `grep /tmp/hsperfdata_root/* -le i2p` /tmp/i2p-*.tmp /tmp/router.ping
}
i2p_restart() {
/bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory restart)"
# We want a FULL cycle here, not the wrappers idea of this!
i2p_stop
i2p_start
}
i2p_status() {

View File

@@ -85,23 +85,26 @@ cp -a ../i2p $PKG/$INSTALL_DIR/
mkdir -p $PKG/install
#############################################################################
# Preconfigureation to make package smaller
# Preconfigureation to make package smaller, and...
# we keep as much as reasonable in the installation directory.
# This makes the install map fairly well to the standard installation.
# It also makes it easier to find the log and pid files!
#############################################################################
cd $PKG/$INSTALL_DIR/i2p
# wrapper.config $INSTALL_PATH and $SYSTEM_java_io_tmpdir
sed "s|\$INSTALL_PATH|$INSTALL_DIR/i2p|g" wrapper.config > a
sed "s|\$SYSTEM_java_io_tmpdir|/var/tmp|g" a > wrapper.config
sed "s|\$INSTALL_PATH|/$INSTALL_DIR/i2p|g" wrapper.config > a
sed "s|\$SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > wrapper.config
# eepget %INSTALL_PATH
sed "s|\$INSTALL_PATH|$INSTALL_DIR/i2p|g" eepget > a
sed "s|\$INSTALL_PATH|/$INSTALL_DIR/i2p|g" eepget > a
rm eepget
mv a eepget
# runplain.sh %INSTALL_PATH and %SYSTEM_java_io_tmpdir
sed "s|%INSTALL_PATH|$INSTALL_DIR/i2p|g" runplain.sh > a
sed "s|%SYSTEM_java_io_tmpdir|/var/tmp|g" a > runplain.sh
sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" runplain.sh > a
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > runplain.sh
# i2prouter %INSTALL_PATH and %SYSTEM_java_io_tmpdir
sed "s|%INSTALL_PATH|$INSTALL_DIR/i2p|g" i2prouter > a
sed "s|%SYSTEM_java_io_tmpdir|/var/tmp|g" a > i2prouter
sed "s|%INSTALL_PATH|/$INSTALL_DIR/i2p|g" i2prouter > a
sed "s|%SYSTEM_java_io_tmpdir|/$INSTALL_DIR/i2p|g" a > i2prouter
chmod 744 ./i2prouter
chmod 744 ./osid

View File

@@ -1,29 +1,38 @@
These instructions are for the 1.5 Android SDK.
These instructions are for a recent Android SDK (1.6 or later)..
Should also still work with a 1.5 SDK.
The build file is not compatible with the 1.1 SDK any more.
1.6 and 2.0 SDKs are untested.
#Download the SDK from http://developer.android.com/sdk/index.html
#Unzip the android SDK in ../../
#So then the android tools will be in ../../android-sdk-linux_x86-1.5_r2/tools/
#So then the android tools will be in ../../android-sdk-linux_86/tools/
#
# now go to the available packages tab, check the box and click refresh,
# and download an SDK Platform
# Since I2P is configured to run on 1.1 or higher
# (API 2) download that one. Otherwise you must change the
# target in default.properties from android-2 to andriod-x
# where x is the API version.
# create a file local.properties with the following line:
# sdk-location=/path/to/your/android-sdk-linux_x86-1.5_r2
# sdk-location=/path/to/your/android-sdk-linux_86
#then build the android apk file:
ant debug
# Create the android 1.5 virtual device
# Create the android 1.1 (API 2) virtual device
# (don't make a custom hardware profile)
../../android-sdk-linux_x86-1.5_r2/tools/android create avd --name i2p --target 2
# A AVD created with the 1.5 SDK will not work with the newer tools
../../android-sdk-linux_86/tools/android create avd --name i2p --target 2
#then run the emulator:
../../android-sdk-linux_x86-1.5_r2/tools/emulator -avd i2p &
../../android-sdk-linux_86/tools/emulator -avd i2p &
#then wait a couple minutes until the emulator is up
#then install the I2P app
ant install
#then run the debugger
../../android-sdk-linux_x86-1.5_r2/tools/ddms &
../../android-sdk-linux_86/tools/ddms &
#to rebuild and reinstall to emulator:
ant reinstall

View File

@@ -113,6 +113,10 @@
<delete file="${external-libs-folder}/crypto.jar" />
</target>
<!-- fix for property name change sometime after SDK 1.5 -->
<property name="android-jar" value="${android.jar}" />
<property name="android-aidl" value="${android.aidl}" />
<!--
================================================================================
From here down copied from SDK platforms/android-1.1/templates/android_rules.xml

View File

@@ -10,7 +10,13 @@ i2np.udp.maxConnections=30
# no I2CP
i2p.dummyClientFacade=true
# for now
i2np.ntcp.enable=false
#i2np.ntcp.enable=false
#
# UDP crashes the JVM, don't know why
#
i2np.udp.enable=false
# no COMM at all!!!
#i2p.vmCommSystem=true
# not on android
i2np.upnp.enable=false
routerconsole.geoip.enable=false

View File

@@ -69,7 +69,7 @@ public class I2PAndroid extends Activity
// from routerconsole ContextHelper
List contexts = RouterContext.listContexts();
if ( (contexts == null) || (contexts.size() <= 0) )
if ( (contexts == null) || (contexts.isEmpty()) )
throw new IllegalStateException("No contexts. This is usually because the router is either starting up or shutting down.");
RouterContext ctx = (RouterContext)contexts.get(0);

View File

@@ -1,8 +0,0 @@
compile.on.save=false
do.depend=false
do.jar=true
javac.debug=true
javadoc.preview=true
jaxbwiz.endorsed.dirs=/usr/local/netbeans-6.8/ide12/modules/ext/jaxb/api
jaxws.endorsed.dir=/usr/local/netbeans-6.5/java2/modules/ext/jaxws21/api:/usr/local/netbeans-6.5/ide10/modules/ext/jaxb/api
user.properties.file=/root/.netbeans/6.5/build.properties

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
</project-private>

View File

@@ -34,7 +34,9 @@ import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.I2PException;
import net.i2p.client.I2PClientFactory;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.util.Log;
// needed only for debugging.
// import java.util.logging.Level;
@@ -50,7 +52,7 @@ public class DoCMDS implements Runnable {
// FIX ME
// I need a better way to do versioning, but this will do for now.
public static final String BMAJ = "00", BMIN = "00", BREV = "0B", BEXT = "";
public static final String BMAJ = "00", BMIN = "00", BREV = "0E", BEXT = "";
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
private Socket server;
private Properties props;
@@ -86,6 +88,7 @@ public class DoCMDS implements Runnable {
private static final String C_inhost = "inhost";
private static final String C_inport = "inport";
private static final String C_list = "list";
private static final String C_lookup = "lookup";
private static final String C_newkeys = "newkeys";
private static final String C_option = "option";
private static final String C_outhost = "outhost";
@@ -113,6 +116,7 @@ public class DoCMDS implements Runnable {
{C_inhost, C_inhost + " hostname | IP * Set the inbound hostname or IP."},
{C_inport, C_inport + " port_number * Set the inbound port number nickname listens on."},
{C_list, C_list + " * List all tunnels."},
{C_lookup, C_lookup + " * Lookup an i2p address."},
{C_newkeys, C_newkeys + " * Generate a new keypair for the current nickname."},
{C_option, C_option + " I2CPoption=something * Set an I2CP option. NOTE: Don't use any spaces."},
{C_outhost, C_outhost + " hostname | IP * Set the outbound hostname or IP."},
@@ -138,6 +142,7 @@ public class DoCMDS implements Runnable {
C_inhost + " " +
C_inport + " " +
C_list + " " +
C_lookup + " " +
C_newkeys + " " +
C_option + " " +
C_outhost + " " +
@@ -446,6 +451,25 @@ public class DoCMDS implements Runnable {
} else if (Command.equals(C_visit)) {
visitAllThreads();
out.println("OK ");
} else if (Command.equals(C_lookup)) {
Destination dest = null;
String reply = null;
if (Arg.endsWith(".i2p")) {
try {
try {
dest = I2PTunnel.destFromName(Arg);
} catch (DataFormatException ex) {
}
reply = dest.toBase64();
} catch (NullPointerException npe) {
// Could not find the destination!?
}
}
if (reply == null) {
out.println("ERROR Address Not found.");
} else {
out.println("OK " + reply);
}
} else if (Command.equals(C_getdest)) {
if (ns) {
if (dk) {

View File

@@ -311,6 +311,19 @@ public class MUXlisten implements Runnable {
} catch (InterruptedException ex) {
}
// Hopefully nuke stuff here...
{
String boner = tg.getName();
try {
_log.warn("destroySocketManager " + boner);
socketManager.destroySocketManager();
_log.warn("destroySocketManager Successful" + boner);
} catch (Exception e) {
// nop
_log.warn("destroySocketManager Failed" + boner);
_log.warn(e.toString());
}
}
// zero out everything.
try {
wlock();

View File

@@ -95,10 +95,14 @@ public class TCPio implements Runnable {
if (b > 0) {
Aout.write(a, 0, b);
} else if (b == 0) {
Thread.yield(); // this should act like a mini sleep.
if (Ain.available() == 0) {
Thread.sleep(10);
// Will this die? We'll see.
while(Ain.available() == 0) {
Thread.sleep(20);
}
// Thread.yield(); // this should act like a mini sleep.
// if (Ain.available() == 0) {
// Thread.sleep(10);
// }
} else {
/* according to the specs:
*

View File

@@ -25,9 +25,9 @@ import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
@@ -35,6 +35,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.i2p.util.SecureFileOutputStream;
/**
* Utility class providing methods to parse and write files in config file
* format, and subscription file format.
@@ -277,7 +279,7 @@ public class ConfigParser {
*/
public static void write(Map map, File file) throws IOException {
ConfigParser
.write(map, new BufferedWriter(new FileWriter(file, false)));
.write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
}
/**
@@ -316,7 +318,7 @@ public class ConfigParser {
public static void writeSubscriptions(List list, File file)
throws IOException {
ConfigParser.writeSubscriptions(list, new BufferedWriter(
new FileWriter(file, false)));
new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
}
}

View File

@@ -29,6 +29,7 @@ import java.util.List;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.util.SecureDirectory;
/**
* Main class of addressbook. Performs updates, and runs the main loop.
@@ -39,6 +40,7 @@ import net.i2p.I2PAppContext;
public class Daemon {
public static final String VERSION = "2.0.3";
private static final Daemon _instance = new Daemon();
private boolean _running;
/**
* Update the router and published address books using remote data from the
@@ -126,14 +128,15 @@ public class Daemon {
}
public void run(String[] args) {
_running = true;
String settingsLocation = "config.txt";
File homeFile;
if (args.length > 0) {
homeFile = new File(args[0]);
homeFile = new SecureDirectory(args[0]);
if (!homeFile.isAbsolute())
homeFile = new File(I2PAppContext.getGlobalContext().getRouterDir(), args[0]);
homeFile = new SecureDirectory(I2PAppContext.getGlobalContext().getRouterDir(), args[0]);
} else {
homeFile = new File(System.getProperty("user.dir"));
homeFile = new SecureDirectory(System.getProperty("user.dir"));
}
Map defaultSettings = new HashMap();
@@ -166,7 +169,7 @@ public class Daemon {
// Static method, and redundent Thread.currentThread().sleep(5*60*1000);
} catch (InterruptedException ie) {}
while (true) {
while (_running) {
long delay = Long.parseLong((String) settings.get("update_delay"));
if (delay < 1) {
delay = 1;
@@ -179,6 +182,8 @@ public class Daemon {
}
} catch (InterruptedException exp) {
}
if (!_running)
break;
settings = ConfigParser.parse(settingsFile, defaultSettings);
}
}
@@ -192,4 +197,9 @@ public class Daemon {
_instance.notifyAll();
}
}
public static void stop() {
_instance._running = false;
wakeup();
}
}

View File

@@ -51,4 +51,9 @@ public class DaemonThread extends Thread {
//}
Daemon.main(this.args);
}
}
public void halt() {
Daemon.stop();
interrupt();
}
}

View File

@@ -41,7 +41,7 @@ import javax.servlet.http.HttpServletResponse;
*
*/
public class Servlet extends HttpServlet {
private Thread thread;
private DaemonThread thread;
private String nonce;
private static final String PROP_NONCE = "addressbook.nonce";
@@ -88,4 +88,9 @@ public class Servlet extends HttpServlet {
//System.out.println("INFO: config root under " + args[0]);
}
@Override
public void destroy() {
this.thread.halt();
super.destroy();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

BIN
apps/i2psnark/_icons/cd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

View File

@@ -52,8 +52,9 @@
<classes dir="./build/obj" includes="**/I2PSnarkServlet*.class" />
-->
<target name="war" depends="jar, bundle">
<war destfile="../i2psnark.war" webxml="../web.xml">
<classes dir="./build/obj" includes="**/*.class" excludes="**/RunStandalone.class" />
<war destfile="../i2psnark.war" webxml="../web.xml" basedir="../" includes="_icons/*" >
<!-- include only the web stuff, as of 0.7.12 the router will add i2psnark.jar to the classpath for the war -->
<classes dir="./build/obj" includes="**/web/*.class" />
</war>
</target>
@@ -72,7 +73,7 @@
</exec>
</target>
<target name="poupdate" depends="compile">
<target name="poupdate" depends="builddep, compile">
<!-- Update the messages_*.po files. -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" >
<arg value="./bundle-messages.sh" />

View File

@@ -49,7 +49,7 @@ do
# To start a new translation, copy the header from an old translation to the new .po file,
# then ant distclean poupdate.
find $JPATHS -name *.java > $TMPFILE
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 --add-comments\
--keyword=_ --keyword=_x \
-o ${i}t
if [ $? -ne 0 ]

View File

@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocket;
@@ -36,7 +37,7 @@ import net.i2p.util.Log;
*/
public class ConnectionAcceptor implements Runnable
{
private Log _log = new Log(ConnectionAcceptor.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ConnectionAcceptor.class);
private I2PServerSocket serverSocket;
private PeerAcceptor peeracceptor;
private Thread thread;

View File

@@ -4,7 +4,6 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -23,9 +22,11 @@ import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.EepGet;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.SecureDirectory;
import net.i2p.util.SimpleScheduler;
import net.i2p.util.SimpleTimer;
import net.i2p.util.Translate;
@@ -45,37 +46,39 @@ public class I2PSnarkUtil {
private int _proxyPort;
private String _i2cpHost;
private int _i2cpPort;
private Map _opts;
private Map<String, String> _opts;
private I2PSocketManager _manager;
private boolean _configured;
private final Set _shitlist;
private final Set<Hash> _shitlist;
private int _maxUploaders;
private int _maxUpBW;
private int _maxConnections;
private File _tmpDir;
private int _startupDelay;
public static final int DEFAULT_STARTUP_DELAY = 3;
public static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers";
public static final boolean DEFAULT_USE_OPENTRACKERS = true;
public static final String PROP_OPENTRACKERS = "i2psnark.opentrackers";
public static final String DEFAULT_OPENTRACKERS = "http://tracker.welterde.i2p/a";
public static final int DEFAULT_MAX_UP_BW = 8; //KBps
public static final int MAX_CONNECTIONS = 16; // per torrent
public I2PSnarkUtil(I2PAppContext ctx) {
_context = ctx;
_log = _context.logManager().getLog(Snark.class);
_opts = new HashMap();
setProxy("127.0.0.1", 4444);
//setProxy("127.0.0.1", 4444);
setI2CPConfig("127.0.0.1", 7654, null);
_shitlist = new HashSet(64);
_shitlist = new ConcurrentHashSet();
_configured = false;
_maxUploaders = Snark.MAX_TOTAL_UPLOADERS;
_maxUpBW = DEFAULT_MAX_UP_BW;
_maxConnections = MAX_CONNECTIONS;
_startupDelay = DEFAULT_STARTUP_DELAY;
// This is used for both announce replies and .torrent file downloads,
// so it must be available even if not connected to I2CP.
// so much for multiple instances
_tmpDir = new File(ctx.getTempDir(), "i2psnark");
_tmpDir = new SecureDirectory(ctx.getTempDir(), "i2psnark");
FileUtil.rmdir(_tmpDir, false);
_tmpDir.mkdirs();
}
@@ -85,6 +88,7 @@ public class I2PSnarkUtil {
* host for no proxying)
*
*/
/*****
public void setProxy(String host, int port) {
if ( (host != null) && (port > 0) ) {
_shouldProxy = true;
@@ -97,6 +101,7 @@ public class I2PSnarkUtil {
}
_configured = true;
}
******/
public boolean configured() { return _configured; }
@@ -125,22 +130,31 @@ public class I2PSnarkUtil {
_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 getI2CPOptions() { return _opts; }
public Map<String, String> getI2CPOptions() { return _opts; }
public String getEepProxyHost() { return _proxyHost; }
public int getEepProxyPort() { return _proxyPort; }
public boolean getEepProxySet() { return _shouldProxy; }
public int getMaxUploaders() { return _maxUploaders; }
public int getMaxUpBW() { return _maxUpBW; }
public int getMaxConnections() { return _maxConnections; }
public int getStartupDelay() { return _startupDelay; }
/**
* Connect to the router, if we aren't already
*/
synchronized public boolean connect() {
if (_manager == null) {
// try to find why reconnecting after stop
if (_log.shouldLog(Log.DEBUG))
_log.debug("Connecting to I2P", new Exception("I did it"));
Properties opts = new Properties();
if (_opts != null) {
for (Iterator iter = _opts.keySet().iterator(); iter.hasNext(); ) {
@@ -152,6 +166,10 @@ public class I2PSnarkUtil {
opts.setProperty("inbound.nickname", "I2PSnark");
if (opts.getProperty("outbound.nickname") == null)
opts.setProperty("outbound.nickname", "I2PSnark");
// Dont do this for now, it is set in I2PSocketEepGet for announces,
// we don't need fast handshake for peer connections.
//if (opts.getProperty("i2p.streaming.connectDelay") == null)
// opts.setProperty("i2p.streaming.connectDelay", "500");
if (opts.getProperty("i2p.streaming.inactivityTimeout") == null)
opts.setProperty("i2p.streaming.inactivityTimeout", "240000");
if (opts.getProperty("i2p.streaming.inactivityAction") == null)
@@ -175,6 +193,7 @@ public class I2PSnarkUtil {
*/
public void disconnect() {
I2PSocketManager mgr = _manager;
// FIXME this can cause race NPEs elsewhere
_manager = null;
_shitlist.clear();
mgr.destroySocketManager();
@@ -186,19 +205,22 @@ public class I2PSnarkUtil {
/** connect to the given destination */
I2PSocket connect(PeerID peer) throws IOException {
Hash dest = peer.getAddress().calculateHash();
synchronized (_shitlist) {
if (_shitlist.contains(dest))
throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are shitlisted");
}
I2PSocketManager mgr = _manager;
if (mgr == null)
throw new IOException("No socket manager");
Destination addr = peer.getAddress();
if (addr == null)
throw new IOException("Null address");
Hash dest = addr.calculateHash();
if (_shitlist.contains(dest))
throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are shitlisted");
try {
I2PSocket rv = _manager.connect(peer.getAddress());
if (rv != null) synchronized (_shitlist) { _shitlist.remove(dest); }
I2PSocket rv = _manager.connect(addr);
if (rv != null)
_shitlist.remove(dest);
return rv;
} catch (I2PException ie) {
synchronized (_shitlist) {
_shitlist.add(dest);
}
_shitlist.add(dest);
SimpleScheduler.getInstance().addEvent(new Unshitlist(dest), 10*60*1000);
throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage());
}
@@ -207,7 +229,7 @@ public class I2PSnarkUtil {
private class Unshitlist implements SimpleTimer.TimedEvent {
private Hash _dest;
public Unshitlist(Hash dest) { _dest = dest; }
public void timeReached() { synchronized (_shitlist) { _shitlist.remove(_dest); } }
public void timeReached() { _shitlist.remove(_dest); }
}
/**
@@ -217,7 +239,8 @@ public class I2PSnarkUtil {
public File get(String url, boolean rewrite) { return get(url, rewrite, 0); }
public File get(String url, int retries) { return get(url, true, retries); }
public File get(String url, boolean rewrite, int retries) {
_log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
File out = null;
try {
// we could use the system tmp dir but deleteOnExit() doesn't seem to work on all platforms...
@@ -241,10 +264,12 @@ public class I2PSnarkUtil {
}
EepGet get = new I2PSocketEepGet(_context, _manager, retries, out.getAbsolutePath(), fetchURL);
if (get.fetch()) {
_log.debug("Fetch successful [" + url + "]: size=" + out.length());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Fetch successful [" + url + "]: size=" + out.length());
return out;
} else {
_log.warn("Fetch failed [" + url + "]");
if (_log.shouldLog(Log.WARN))
_log.warn("Fetch failed [" + url + "]");
out.delete();
return null;
}
@@ -358,7 +383,7 @@ public class I2PSnarkUtil {
while (tok.hasMoreTokens())
rv.add(tok.nextToken());
if (rv.size() <= 0)
if (rv.isEmpty())
return null;
return rv;
}
@@ -431,4 +456,9 @@ public class I2PSnarkUtil {
public String getString(String s, Object o, Object o2) {
return Translate.getString(s, o, o2, _context, BUNDLE_NAME);
}
/** ngettext @since 0.7.14 */
public String getString(int n, String s, String p) {
return Translate.getString(n, s, p, _context, BUNDLE_NAME);
}
}

View File

@@ -30,6 +30,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.crypto.SHA1;
import net.i2p.data.Base64;
import net.i2p.util.Log;
@@ -47,7 +48,7 @@ import org.klomp.snark.bencode.InvalidBEncodingException;
*/
public class MetaInfo
{
private static final Log _log = new Log(MetaInfo.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(MetaInfo.class);
private final String announce;
private final byte[] info_hash;
private final String name;
@@ -108,7 +109,8 @@ public class MetaInfo
*/
public MetaInfo(Map m) throws InvalidBEncodingException
{
_log.debug("Creating a metaInfo: " + m, new Exception("source"));
if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating a metaInfo: " + m, new Exception("source"));
BEValue val = (BEValue)m.get("announce");
if (val == null)
throw new InvalidBEncodingException("Missing announce string");
@@ -445,14 +447,16 @@ public class MetaInfo
else
buf.append(val.toString());
}
_log.debug(buf.toString());
if (_log.shouldLog(Log.DEBUG))
_log.debug(buf.toString());
byte[] infoBytes = BEncoder.bencode(info);
//_log.debug("info bencoded: [" + Base64.encode(infoBytes, true) + "]");
try
{
MessageDigest digest = MessageDigest.getInstance("SHA");
byte hash[] = digest.digest(infoBytes);
_log.debug("info hash: [" + net.i2p.data.Base64.encode(hash) + "]");
if (_log.shouldLog(Log.DEBUG))
_log.debug("info hash: [" + net.i2p.data.Base64.encode(hash) + "]");
return hash;
}
catch(NoSuchAlgorithmException nsa)

View File

@@ -56,8 +56,8 @@ public class Peer implements Comparable
private long _id;
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,-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1};
private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1};
/**
* Creates a disconnected peer given a PeerID, your own id and the
@@ -92,7 +92,8 @@ public class Peer implements Comparable
byte[] id = handshake(in, out);
this.peerID = new PeerID(id, sock.getPeerDestination());
_id = ++__id;
_log.debug("Creating a new peer with " + peerID.getAddress().calculateHash().toBase64(), new Exception("creating " + _id));
if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating a new peer with " + peerID.getAddress().calculateHash().toBase64(), new Exception("creating " + _id));
}
/**
@@ -116,10 +117,15 @@ public class Peer implements Comparable
}
/**
* Returns socket (for debug printing)
* @return socket debug string (for debug printing)
*/
public String getSocket()
{
if (state != null) {
String r = state.getRequests();
if (r != null)
return sock.toString() + "<br>Requests: " + r;
}
return sock.toString();
}
@@ -129,7 +135,7 @@ public class Peer implements Comparable
@Override
public int hashCode()
{
return peerID.hashCode() ^ (2 << _id);
return peerID.hashCode() ^ (7777 * (int)_id);
}
/**
@@ -150,6 +156,7 @@ public class Peer implements Comparable
/**
* Compares the PeerIDs.
* @deprecated unused?
*/
public int compareTo(Object o)
{
@@ -181,14 +188,16 @@ public class Peer implements Comparable
if (state != null)
throw new IllegalStateException("Peer already started");
_log.debug("Running connection to " + peerID.getAddress().calculateHash().toBase64(), new Exception("connecting"));
if (_log.shouldLog(Log.DEBUG))
_log.debug("Running connection to " + peerID.getAddress().calculateHash().toBase64(), new Exception("connecting"));
try
{
// Do we need to handshake?
if (din == null)
{
sock = util.connect(peerID);
_log.debug("Connected to " + peerID + ": " + sock);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Connected to " + peerID + ": " + sock);
if ((sock == null) || (sock.isClosed())) {
throw new IOException("Unable to reach " + peerID);
}
@@ -207,14 +216,20 @@ public class Peer implements Comparable
// = new BufferedOutputStream(sock.getOutputStream());
byte [] id = handshake(in, out); //handshake(bis, bos);
byte [] expected_id = peerID.getID();
if (!Arrays.equals(expected_id, id))
throw new IOException("Unexpected peerID '"
if (expected_id == null) {
peerID.setID(id);
} else if (Arrays.equals(expected_id, id)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Handshake got matching IDs with " + toString());
} else {
throw new IOException("Unexpected peerID '"
+ PeerID.idencode(id)
+ "' expected '"
+ PeerID.idencode(expected_id) + "'");
_log.debug("Handshake got matching IDs with " + toString());
}
} else {
_log.debug("Already have din [" + sock + "] with " + toString());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Already have din [" + sock + "] with " + toString());
}
PeerConnectionIn in = new PeerConnectionIn(this, din);
@@ -229,7 +244,8 @@ public class Peer implements Comparable
state = s;
listener.connected(this);
_log.debug("Start running the reader with " + toString());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Start running the reader with " + toString());
// Use this thread for running the incomming connection.
// The outgoing connection creates its own Thread.
out.startup();
@@ -279,7 +295,8 @@ public class Peer implements Comparable
dout.write(my_id);
dout.flush();
_log.debug("Wrote my shared hash and ID to " + toString());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Wrote my shared hash and ID to " + toString());
// Handshake read - header
byte b = din.readByte();
@@ -306,7 +323,8 @@ public class Peer implements Comparable
// Handshake read - peer id
din.readFully(bs);
_log.debug("Read the remote side's hash and peerID fully from " + toString());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Read the remote side's hash and peerID fully from " + toString());
return bs;
}
@@ -374,6 +392,37 @@ public class Peer implements Comparable
s.havePiece(piece);
}
/**
* Tell the other side that we are no longer interested in any of
* the outstanding requests (if any) for this piece.
* @since 0.8.1
*/
void cancel(int piece) {
PeerState s = state;
if (s != null)
s.cancelPiece(piece);
}
/**
* Are we currently requesting the piece?
* @since 0.8.1
*/
boolean isRequesting(int p) {
PeerState s = state;
return s != null && s.isRequesting(p);
}
/**
* Update the request queue.
* Call after adding wanted pieces.
* @since 0.8.1
*/
void request() {
PeerState s = state;
if (s != null)
s.addRequest();
}
/**
* Whether or not the peer is interested in pieces we have. Returns
* false if not connected.
@@ -388,6 +437,7 @@ public class Peer implements Comparable
* Sets whether or not we are interested in pieces from this peer.
* Defaults to false. When interest is true and this peer unchokes
* us then we start downloading from it. Has no effect when not connected.
* @deprecated unused
*/
public void setInteresting(boolean interest)
{
@@ -531,17 +581,8 @@ public class Peer implements Comparable
*/
public void setRateHistory(long up, long down)
{
setRate(up, uploaded_old);
setRate(down, downloaded_old);
}
private void setRate(long val, long array[])
{
synchronized(array) {
for (int i = RATE_DEPTH-1; i > 0; i--)
array[i] = array[i-1];
array[0] = val;
}
PeerCoordinator.setRate(up, uploaded_old);
PeerCoordinator.setRate(down, downloaded_old);
}
/**
@@ -549,28 +590,11 @@ public class Peer implements Comparable
*/
public long getUploadRate()
{
return getRate(uploaded_old);
return PeerCoordinator.getRate(uploaded_old);
}
public long getDownloadRate()
{
return getRate(downloaded_old);
return PeerCoordinator.getRate(downloaded_old);
}
private long getRate(long array[])
{
long rate = 0;
int i = 0;
synchronized(array) {
for ( ; i < RATE_DEPTH; i++){
if (array[i] < 0)
break;
rate += array[i];
}
}
if (i == 0)
return 0;
return rate / (i * CHECK_PERIOD / 1000);
}
}

View File

@@ -28,6 +28,7 @@ import java.io.OutputStream;
import java.io.SequenceInputStream;
import java.util.Iterator;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
@@ -41,7 +42,7 @@ import net.i2p.util.Log;
*/
public class PeerAcceptor
{
private static final Log _log = new Log(PeerAcceptor.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerAcceptor.class);
private final PeerCoordinator coordinator;
final PeerCoordinatorSet coordinators;
@@ -75,10 +76,12 @@ public class PeerAcceptor
// is this working right?
try {
peerInfoHash = readHash(in);
_log.info("infohash read from " + socket.getPeerDestination().calculateHash().toBase64()
+ ": " + Base64.encode(peerInfoHash));
if (_log.shouldLog(Log.INFO))
_log.info("infohash read from " + socket.getPeerDestination().calculateHash().toBase64()
+ ": " + Base64.encode(peerInfoHash));
} catch (IOException ioe) {
_log.info("Unable to read the infohash from " + socket.getPeerDestination().calculateHash().toBase64());
if (_log.shouldLog(Log.INFO))
_log.info("Unable to read the infohash from " + socket.getPeerDestination().calculateHash().toBase64());
throw ioe;
}
in = new SequenceInputStream(new ByteArrayInputStream(peerInfoHash), in);

View File

@@ -26,6 +26,8 @@ import java.util.List;
import java.util.Random;
import java.util.TimerTask;
import net.i2p.I2PAppContext;
/**
* TimerTask that checks for good/bad up/downloader. Works together
* with the PeerCoordinator to select which Peers get (un)choked.
@@ -43,7 +45,7 @@ class PeerCheckerTask extends TimerTask
this.coordinator = coordinator;
}
private Random random = new Random();
private static final Random random = I2PAppContext.getGlobalContext().random();
public void run()
{
@@ -113,7 +115,7 @@ class PeerCheckerTask extends TimerTask
+ " C: " + peer.isChoked(),
Snark.DEBUG);
// Choke half of them rather than all so it isn't so drastic...
// Choke a percentage of them rather than all so it isn't so drastic...
// unless this torrent is over the limit all by itself.
boolean overBWLimitChoke = upload > 0 &&
((overBWLimit && random.nextBoolean()) ||

View File

@@ -23,11 +23,12 @@ package org.klomp.snark;
import java.io.DataInputStream;
import java.io.IOException;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
class PeerConnectionIn implements Runnable
{
private Log _log = new Log(PeerConnectionIn.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerConnectionIn.class);
private final Peer peer;
private final DataInputStream din;
@@ -129,7 +130,7 @@ class PeerConnectionIn implements Runnable
din.readFully(bitmap);
ps.bitfieldMessage(bitmap);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received bitmap from " + peer + " on " + peer.metainfo.getName() + ": size=" + (i-1) + ": " + ps.bitfield);
_log.debug("Received bitmap from " + peer + " on " + peer.metainfo.getName() + ": size=" + (i-1) /* + ": " + ps.bitfield */ );
break;
case 6:
piece = din.readInt();

View File

@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.SimpleScheduler;
@@ -33,7 +34,7 @@ import net.i2p.util.SimpleTimer;
class PeerConnectionOut implements Runnable
{
private Log _log = new Log(PeerConnectionOut.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerConnectionOut.class);
private final Peer peer;
private final DataOutputStream dout;
@@ -141,7 +142,7 @@ class PeerConnectionOut implements Runnable
it.remove();
}
}
if (m == null && sendQueue.size() > 0) {
if (m == null && !sendQueue.isEmpty()) {
m = (Message)sendQueue.remove(0);
SimpleTimer.getInstance().removeEvent(m.expireEvent);
}
@@ -151,7 +152,11 @@ class PeerConnectionOut implements Runnable
{
if (_log.shouldLog(Log.DEBUG))
_log.debug("Send " + peer + ": " + m + " on " + peer.metainfo.getName());
m.sendMessage(dout);
// This can block for quite a while.
// To help get slow peers going, and track the bandwidth better,
// move this _after_ state.uploaded() and see how it works.
//m.sendMessage(dout);
lastSent = System.currentTimeMillis();
// Remove all piece messages after sending a choke message.
@@ -159,9 +164,22 @@ class PeerConnectionOut implements Runnable
removeMessage(Message.PIECE);
// XXX - Should also register overhead...
if (m.type == Message.PIECE)
state.uploaded(m.len);
// Don't let other clients requesting big chunks get an advantage
// when we are seeding;
// only count the rest of the upload after sendMessage().
int remainder = 0;
if (m.type == Message.PIECE) {
if (m.len <= PeerState.PARTSIZE) {
state.uploaded(m.len);
} else {
state.uploaded(PeerState.PARTSIZE);
remainder = m.len - PeerState.PARTSIZE;
}
}
m.sendMessage(dout);
if (remainder > 0)
state.uploaded(remainder);
m = null;
}
}

View File

@@ -29,6 +29,7 @@ import java.util.List;
import java.util.Random;
import java.util.Timer;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
@@ -37,7 +38,7 @@ import net.i2p.util.Log;
*/
public class PeerCoordinator implements PeerListener
{
private final Log _log = new Log(PeerCoordinator.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerCoordinator.class);
final MetaInfo metainfo;
final Storage storage;
final Snark snark;
@@ -56,12 +57,12 @@ public class PeerCoordinator implements PeerListener
private long uploaded;
private long downloaded;
final static int RATE_DEPTH = 6; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1};
final static int RATE_DEPTH = 3; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1};
// synchronize on this when changing peers or downloaders
final List peers = new ArrayList();
final List<Peer> peers = new ArrayList();
/** estimate of the peers, without requiring any synchronization */
volatile int peerCount;
@@ -71,12 +72,13 @@ public class PeerCoordinator implements PeerListener
private final byte[] id;
// Some random wanted pieces
private List wantedPieces;
private List<Piece> wantedPieces;
private boolean halted = false;
private final CoordinatorListener listener;
public I2PSnarkUtil _util;
private static final Random _random = I2PAppContext.getGlobalContext().random();
public String trackerProblems = null;
public int trackerSeenPeers = 0;
@@ -96,27 +98,36 @@ public class PeerCoordinator implements PeerListener
// Install a timer to check the uploaders.
// Randomize the first start time so multiple tasks are spread out,
// this will help the behavior with global limits
Random r = new Random();
timer.schedule(new PeerCheckerTask(_util, this), (CHECK_PERIOD / 2) + r.nextInt((int) CHECK_PERIOD), CHECK_PERIOD);
timer.schedule(new PeerCheckerTask(_util, this), (CHECK_PERIOD / 2) + _random.nextInt((int) CHECK_PERIOD), CHECK_PERIOD);
}
// only called externally from Storage after the double-check fails
public void setWantedPieces()
{
// Make a list of pieces
// FIXME synchronize, clear and re-add instead?
// Don't replace something we are synchronizing on.
wantedPieces = new ArrayList();
BitField bitfield = storage.getBitField();
for(int i = 0; i < metainfo.getPieces(); i++)
if (!bitfield.get(i))
wantedPieces.add(new Piece(i));
Collections.shuffle(wantedPieces);
int[] pri = storage.getPiecePriorities();
for(int i = 0; i < metainfo.getPieces(); i++) {
// only add if we don't have and the priority is >= 0
if ((!bitfield.get(i)) &&
(pri == null || pri[i] >= 0)) {
Piece p = new Piece(i);
if (pri != null)
p.setPriority(pri[i]);
wantedPieces.add(p);
}
}
Collections.shuffle(wantedPieces, _random);
}
public Storage getStorage() { return storage; }
public CoordinatorListener getListener() { return listener; }
// for web page detailed stats
public List peerList()
public List<Peer> peerList()
{
synchronized(peers)
{
@@ -134,8 +145,10 @@ public class PeerCoordinator implements PeerListener
return storage.complete();
}
/** might be wrong */
public int getPeerCount() { return peerCount; }
/** should be right */
public int getPeers()
{
synchronized(peers)
@@ -180,7 +193,7 @@ public class PeerCoordinator implements PeerListener
setRate(down, downloaded_old);
}
private static void setRate(long val, long array[])
static void setRate(long val, long array[])
{
synchronized(array) {
for (int i = RATE_DEPTH-1; i > 0; i--)
@@ -211,20 +224,23 @@ public class PeerCoordinator implements PeerListener
return (r * 1000) / CHECK_PERIOD;
}
private long getRate(long array[])
static long getRate(long array[])
{
long rate = 0;
int i = 0;
int factor = 0;
synchronized(array) {
for ( ; i < RATE_DEPTH; i++) {
if (array[i] < 0)
break;
rate += array[i];
int f = RATE_DEPTH - i;
rate += array[i] * f;
factor += f;
}
}
if (i == 0)
return 0;
return rate / (i * CHECK_PERIOD / 1000);
return rate / (factor * CHECK_PERIOD / 1000);
}
public MetaInfo getMetaInfo()
@@ -240,15 +256,18 @@ public class PeerCoordinator implements PeerListener
}
}
/** reduce max if huge pieces to keep from ooming */
/**
* Reduce max if huge pieces to keep from ooming when leeching
* @return 512K: 16; 1M: 11; 2M: 6
*/
private int getMaxConnections() {
int size = metainfo.getPieceLength(0);
int max = _util.getMaxConnections();
if (size <= 1024*1024)
if (size <= 512*1024 || completed())
return max;
if (size <= 2*1024*1024)
return (max + 1) / 2;
return (max + 3) / 4;
if (size <= 1024*1024)
return (max + max + 2) / 3;
return (max + 2) / 3;
}
public boolean halted() { return halted; }
@@ -256,7 +275,7 @@ public class PeerCoordinator implements PeerListener
public void halt()
{
halted = true;
List removed = new ArrayList();
List<Peer> removed = new ArrayList();
synchronized(peers)
{
// Stop peer checker task.
@@ -268,8 +287,8 @@ public class PeerCoordinator implements PeerListener
peerCount = 0;
}
while (removed.size() > 0) {
Peer peer = (Peer)removed.remove(0);
while (!removed.isEmpty()) {
Peer peer = removed.remove(0);
peer.disconnect();
removePeerFromPieces(peer);
}
@@ -336,9 +355,9 @@ public class PeerCoordinator implements PeerListener
// caller must synchronize on peers
private static Peer peerIDInList(PeerID pid, List peers)
{
Iterator it = peers.iterator();
Iterator<Peer> it = peers.iterator();
while (it.hasNext()) {
Peer cur = (Peer)it.next();
Peer cur = it.next();
if (pid.sameID(cur.getPeerID()))
return cur;
}
@@ -369,7 +388,8 @@ public class PeerCoordinator implements PeerListener
if (need_more)
{
_log.debug("Adding a peer " + peer.getPeerID().getAddress().calculateHash().toBase64() + " for " + metainfo.getName(), new Exception("add/run"));
if (_log.shouldLog(Log.DEBUG))
_log.debug("Adding a peer " + peer.getPeerID().toString() + " for " + metainfo.getName(), new Exception("add/run"));
// Run the peer with us as listener and the current bitfield.
final PeerListener listener = this;
@@ -402,15 +422,15 @@ public class PeerCoordinator implements PeerListener
// linked list will contain all interested peers that we choke.
// At the start are the peers that have us unchoked at the end the
// other peer that are interested, but are choking us.
List interested = new LinkedList();
List<Peer> interested = new LinkedList();
synchronized (peers) {
int count = 0;
int unchokedCount = 0;
int maxUploaders = allowedUploaders();
Iterator it = peers.iterator();
Iterator<Peer> it = peers.iterator();
while (it.hasNext())
{
Peer peer = (Peer)it.next();
Peer peer = it.next();
if (peer.isChoking() && peer.isInterested())
{
count++;
@@ -424,9 +444,9 @@ public class PeerCoordinator implements PeerListener
}
}
while (uploaders < maxUploaders && interested.size() > 0)
while (uploaders < maxUploaders && !interested.isEmpty())
{
Peer peer = (Peer)interested.remove(0);
Peer peer = interested.remove(0);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unchoke: " + peer);
peer.setChoking(false);
@@ -447,7 +467,7 @@ public class PeerCoordinator implements PeerListener
}
/**
* Returns true if we don't have the given piece yet.
* @return true if we still want the given piece
*/
public boolean gotHave(Peer peer, int piece)
{
@@ -471,10 +491,10 @@ public class PeerCoordinator implements PeerListener
synchronized(wantedPieces)
{
Iterator it = wantedPieces.iterator();
Iterator<Piece> it = wantedPieces.iterator();
while (it.hasNext())
{
Piece p = (Piece)it.next();
Piece p = it.next();
int i = p.getId();
if (bitfield.get(i)) {
p.addPeer(peer);
@@ -485,6 +505,19 @@ public class PeerCoordinator implements PeerListener
return false;
}
/**
* This should be somewhat less than the max conns per torrent,
* but not too much less, so a torrent doesn't get stuck near the end.
* @since 0.7.14
*/
private static final int END_GAME_THRESHOLD = 8;
/**
* Max number of peers to get a piece from when in end game
* @since 0.8.1
*/
private static final int MAX_PARALLEL_REQUESTS = 4;
/**
* Returns one of pieces in the given BitField that is still wanted or
* -1 if none of the given pieces are wanted.
@@ -501,11 +534,14 @@ public class PeerCoordinator implements PeerListener
{
Piece piece = null;
Collections.sort(wantedPieces); // Sort in order of rarest first.
List requested = new ArrayList();
Iterator it = wantedPieces.iterator();
List<Piece> requested = new ArrayList();
Iterator<Piece> it = wantedPieces.iterator();
while (piece == null && it.hasNext())
{
Piece p = (Piece)it.next();
Piece p = it.next();
// sorted by priority, so when we hit a disabled piece we are done
if (p.isDisabled())
break;
if (havePieces.get(p.getId()) && !p.isRequested())
{
piece = p;
@@ -518,16 +554,38 @@ public class PeerCoordinator implements PeerListener
//Only request a piece we've requested before if there's no other choice.
if (piece == null) {
// AND if there are almost no wanted pieces left (real end game).
// If we do end game all the time, we generate lots of extra traffic
// when the seeder is super-slow and all the peers are "caught up"
if (wantedPieces.size() > END_GAME_THRESHOLD)
return -1; // nothing to request and not in end game
// let's not all get on the same piece
Collections.shuffle(requested);
Iterator it2 = requested.iterator();
// Even better would be to sort by number of requests
Collections.shuffle(requested, _random);
Iterator<Piece> it2 = requested.iterator();
while (piece == null && it2.hasNext())
{
Piece p = (Piece)it2.next();
if (havePieces.get(p.getId()))
{
Piece p = it2.next();
if (havePieces.get(p.getId())) {
// limit number of parallel requests
int requestedCount = 0;
synchronized(peers) {
for (Peer pr : peers) {
if (pr.isRequesting(p.getId())) {
if (pr.equals(peer)) {
// don't give it to him again
requestedCount = MAX_PARALLEL_REQUESTS;
break;
}
if (++requestedCount >= MAX_PARALLEL_REQUESTS)
break;
}
}
}
if (requestedCount >= MAX_PARALLEL_REQUESTS)
continue;
piece = p;
}
}
}
if (piece == null) {
if (_log.shouldLog(Log.WARN))
@@ -536,7 +594,7 @@ public class PeerCoordinator implements PeerListener
// + " wanted = " + wantedPieces + " peerHas = " + havePieces);
return -1; //If we still can't find a piece we want, so be it.
} else {
// Should be a lot smarter here - limit # of parallel attempts and
// Should be a lot smarter here -
// share blocks rather than starting from 0 with each peer.
// This is where the flaws of the snark data model are really exposed.
// Could also randomize within the duplicate set rather than strict rarest-first
@@ -544,11 +602,83 @@ public class PeerCoordinator implements PeerListener
_log.debug("parallel request (end game?) for " + peer + ": piece = " + piece);
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Now requesting: piece " + piece + " priority " + piece.getPriority());
piece.setRequested(true);
return piece.getId();
}
}
/**
* Maps file priorities to piece priorities.
* Call after updating file priorities Storage.setPriority()
* @since 0.8.1
*/
public void updatePiecePriorities() {
int[] pri = storage.getPiecePriorities();
if (pri == null) {
_log.debug("Updated piece priorities called but no priorities to set?");
return;
}
synchronized(wantedPieces) {
// Add incomplete and previously unwanted pieces to the list
// Temp to avoid O(n**2)
BitField want = new BitField(pri.length);
for (Piece p : wantedPieces) {
want.set(p.getId());
}
BitField bitfield = storage.getBitField();
for (int i = 0; i < pri.length; i++) {
if (pri[i] >= 0 && !bitfield.get(i)) {
if (!want.get(i)) {
Piece piece = new Piece(i);
wantedPieces.add(piece);
// As connections are already up, new Pieces will
// not have their PeerID list populated, so do that.
synchronized(peers) {
for (Peer p : peers) {
PeerState s = p.state;
if (s != null) {
BitField bf = s.bitfield;
if (bf != null && bf.get(i))
piece.addPeer(p);
}
}
}
}
}
}
// now set the new priorities and remove newly unwanted pieces
for (Iterator<Piece> iter = wantedPieces.iterator(); iter.hasNext(); ) {
Piece p = iter.next();
int priority = pri[p.getId()];
if (priority >= 0) {
p.setPriority(priority);
} else {
iter.remove();
// cancel all peers
synchronized(peers) {
for (Peer peer : peers) {
peer.cancel(p.getId());
}
}
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Updated piece priorities, now wanted: " + wantedPieces);
// if we added pieces, they will be in-order unless we shuffle
Collections.shuffle(wantedPieces, _random);
// update request queues, in case we added wanted pieces
// and we were previously uninterested
synchronized(peers) {
for (Peer peer : peers) {
peer.request();
}
}
}
}
/**
* Returns a byte array containing the requested piece or null of
* the piece is unknown.
@@ -613,14 +743,18 @@ public class PeerCoordinator implements PeerListener
// No need to announce have piece to peers.
// Assume we got a good piece, we don't really care anymore.
return true;
// Well, this could be caused by a change in priorities, so
// only return true if we already have it, otherwise might as well keep it.
if (storage.getBitField().get(piece))
return true;
}
try
{
if (storage.putPiece(piece, bs))
{
_log.info("Got valid piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
if (_log.shouldLog(Log.INFO))
_log.info("Got valid piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
}
else
{
@@ -643,11 +777,11 @@ public class PeerCoordinator implements PeerListener
// Disconnect from other seeders when we get the last piece
synchronized(peers)
{
List toDisconnect = new ArrayList();
Iterator it = peers.iterator();
List<Peer> toDisconnect = new ArrayList();
Iterator<Peer> it = peers.iterator();
while (it.hasNext())
{
Peer p = (Peer)it.next();
Peer p = it.next();
if (p.isConnected())
{
if (completed() && p.isCompleted())
@@ -659,7 +793,7 @@ public class PeerCoordinator implements PeerListener
it = toDisconnect.iterator();
while (it.hasNext())
{
Peer p = (Peer)it.next();
Peer p = it.next();
p.disconnect(true);
}
}
@@ -725,8 +859,8 @@ public class PeerCoordinator implements PeerListener
*/
public void removePeerFromPieces(Peer peer) {
synchronized(wantedPieces) {
for(Iterator iter = wantedPieces.iterator(); iter.hasNext(); ) {
Piece piece = (Piece)iter.next();
for(Iterator<Piece> iter = wantedPieces.iterator(); iter.hasNext(); ) {
Piece piece = iter.next();
piece.removePeer(peer);
}
}
@@ -780,8 +914,8 @@ public class PeerCoordinator implements PeerListener
}
synchronized(wantedPieces)
{
for(Iterator iter = wantedPieces.iterator(); iter.hasNext(); ) {
Piece piece = (Piece)iter.next();
for(Iterator<Piece> iter = wantedPieces.iterator(); iter.hasNext(); ) {
Piece piece = iter.next();
if (piece.getId() == savedRequest.piece) {
Request req = savedRequest;
piece.setRequested(true);
@@ -806,9 +940,9 @@ public class PeerCoordinator implements PeerListener
// see if anybody else is requesting
synchronized (peers)
{
Iterator it = peers.iterator();
Iterator<Peer> it = peers.iterator();
while (it.hasNext()) {
Peer p = (Peer)it.next();
Peer p = it.next();
if (p.equals(peer))
continue;
if (p.state == null)
@@ -826,9 +960,9 @@ public class PeerCoordinator implements PeerListener
// nobody is, so mark unrequested
synchronized(wantedPieces)
{
Iterator it = wantedPieces.iterator();
Iterator<Piece> it = wantedPieces.iterator();
while (it.hasNext()) {
Piece p = (Piece)it.next();
Piece p = it.next();
if (p.getId() == piece) {
p.setRequested(false);
if (_log.shouldLog(Log.DEBUG))

View File

@@ -24,19 +24,33 @@ import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.data.Base32;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import org.klomp.snark.bencode.BDecoder;
import org.klomp.snark.bencode.BEValue;
import org.klomp.snark.bencode.InvalidBEncodingException;
/**
* Store the address information about a peer.
* Prior to 0.8.1, an instantiation required a peer ID, and full Destination address.
* Starting with 0.8.1, to support compact tracker responses,
* a PeerID can be instantiated with a Destination Hash alone.
* The full destination lookup is deferred until getAddress() is called,
* and the PeerID is not required.
* Equality is now determined solely by the dest hash.
*/
public class PeerID implements Comparable
{
private final byte[] id;
private final Destination address;
private byte[] id;
private Destination address;
private final int port;
private byte[] destHash;
/** whether we have tried to get the dest from the hash - only do once */
private boolean triedDestLookup;
private final int hash;
public PeerID(byte[] id, Destination address)
@@ -44,7 +58,7 @@ public class PeerID implements Comparable
this.id = id;
this.address = address;
this.port = 6881;
this.destHash = address.calculateHash().getData();
hash = calculateHash();
}
@@ -77,17 +91,49 @@ public class PeerID implements Comparable
throw new InvalidBEncodingException("Invalid destination [" + bevalue.getString() + "]");
port = 6881;
this.destHash = address.calculateHash().getData();
hash = calculateHash();
}
/**
* Creates a PeerID from a destHash
* @since 0.8.1
*/
public PeerID(byte[] dest_hash) throws InvalidBEncodingException
{
// id and address remain null
port = 6881;
if (dest_hash.length != 32)
throw new InvalidBEncodingException("bad hash length");
destHash = dest_hash;
hash = DataHelper.hashCode(dest_hash);
}
public byte[] getID()
{
return id;
}
public Destination getAddress()
/** for connecting out to peer based on desthash @since 0.8.1 */
public void setID(byte[] xid)
{
id = xid;
}
/**
* Get the destination.
* If this PeerId was instantiated with a destHash,
* and we have not yet done so, lookup the full destination, which may take
* up to 10 seconds.
* @return Dest or null if unknown
*/
public synchronized Destination getAddress()
{
if (address == null && destHash != null && !triedDestLookup) {
String b32 = Base32.encode(destHash) + ".b32.i2p";
address = I2PAppContext.getGlobalContext().namingService().lookup(b32);
triedDestLookup = true;
}
return address;
}
@@ -96,16 +142,19 @@ public class PeerID implements Comparable
return port;
}
/** @since 0.8.1 */
public byte[] getDestHash()
{
return destHash;
}
private int calculateHash()
{
int b = 0;
for (int i = 0; i < id.length; i++)
b ^= id[i];
return (b ^ address.hashCode()) ^ port;
return DataHelper.hashCode(destHash);
}
/**
* The hash code of a PeerID is the exclusive or of all id bytes.
* The hash code of a PeerID is the hashcode of the desthash
*/
@Override
public int hashCode()
@@ -115,18 +164,15 @@ public class PeerID implements Comparable
/**
* Returns true if and only if this peerID and the given peerID have
* the same 20 bytes as ID.
* the same destination hash
*/
public boolean sameID(PeerID pid)
{
boolean equal = true;
for (int i = 0; equal && i < id.length; i++)
equal = id[i] == pid.id[i];
return equal;
return DataHelper.eq(destHash, pid.getDestHash());
}
/**
* Two PeerIDs are equal when they have the same id, address and port.
* Two PeerIDs are equal when they have the same dest hash
*/
@Override
public boolean equals(Object o)
@@ -135,9 +181,7 @@ public class PeerID implements Comparable
{
PeerID pid = (PeerID)o;
return port == pid.port
&& address.equals(pid.address)
&& sameID(pid);
return sameID(pid);
}
else
return false;
@@ -145,6 +189,7 @@ public class PeerID implements Comparable
/**
* Compares port, address and id.
* @deprecated unused? and will NPE now that address can be null?
*/
public int compareTo(Object o)
{
@@ -176,6 +221,8 @@ public class PeerID implements Comparable
@Override
public String toString()
{
if (id == null || address == null)
return "unkn@" + Base64.encode(destHash).substring(0, 6);
int nonZero = 0;
for (int i = 0; i < id.length; i++) {
if (id[i] != 0) {

View File

@@ -24,11 +24,12 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
class PeerState
{
private Log _log = new Log(PeerState.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(PeerState.class);
final Peer peer;
final PeerListener listener;
final MetaInfo metainfo;
@@ -54,12 +55,10 @@ class PeerState
final PeerConnectionOut out;
// Outstanding request
private final List outstandingRequests = new ArrayList();
private final List<Request> outstandingRequests = new ArrayList();
/** the tail (NOT the head) of the request queue */
private Request lastRequest = null;
// If we have te resend outstanding requests (true after we got choked).
private boolean resend = false;
private final static int MAX_PIPELINE = 5; // this is for outbound requests
private final static int MAX_PIPELINE_BYTES = 128*1024; // this is for inbound requests
public final static int PARTSIZE = 16*1024; // outbound request
@@ -90,14 +89,13 @@ class PeerState
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " rcv " + (choke ? "" : "un") + "choked");
boolean resend = choked && !choke;
choked = choke;
if (choked)
resend = true;
listener.gotChoke(peer, choke);
if (!choked && interesting)
request();
if (interesting && !choked)
request(resend);
}
void interestedMessage(boolean interest)
@@ -152,7 +150,16 @@ class PeerState
// XXX - Check for weird bitfield and disconnect?
bitfield = new BitField(bitmap, metainfo.getPieces());
}
setInteresting(listener.gotBitField(peer, bitfield));
boolean interest = listener.gotBitField(peer, bitfield);
setInteresting(interest);
if (bitfield.complete() && !interest) {
// They are seeding and we are seeding,
// why did they contact us? (robert)
// Dump them quick before we send our whole bitmap
if (_log.shouldLog(Log.WARN))
_log.warn("Disconnecting seed that connects to seeds: " + peer);
peer.disconnect(true);
}
}
void requestMessage(int piece, int begin, int length)
@@ -186,6 +193,7 @@ class PeerState
// Limit total pipelined requests to MAX_PIPELINE bytes
// to conserve memory and prevent DOS
// Todo: limit number of requests also? (robert 64 x 4KB)
if (out.queuedBytes() + length > MAX_PIPELINE_BYTES)
{
if (_log.shouldLog(Log.WARN))
@@ -267,7 +275,7 @@ class PeerState
synchronized private int getFirstOutstandingRequest(int piece)
{
for (int i = 0; i < outstandingRequests.size(); i++)
if (((Request)outstandingRequests.get(i)).piece == piece)
if (outstandingRequests.get(i).piece == piece)
return i;
return -1;
}
@@ -302,12 +310,12 @@ class PeerState
Request req;
synchronized(this)
{
req = (Request)outstandingRequests.get(r);
req = outstandingRequests.get(r);
while (req.piece == piece && req.off != begin
&& r < outstandingRequests.size() - 1)
{
r++;
req = (Request)outstandingRequests.get(r);
req = outstandingRequests.get(r);
}
// Something wrong?
@@ -331,7 +339,7 @@ class PeerState
+ ", wanted for peer: " + peer);
for (int i = 0; i < r; i++)
{
Request dropReq = (Request)outstandingRequests.remove(0);
Request dropReq = outstandingRequests.remove(0);
outstandingRequests.add(dropReq);
if (!choked)
out.sendRequest(dropReq);
@@ -355,11 +363,11 @@ class PeerState
{
Request req = null;
for (int i = 0; i < outstandingRequests.size(); i++) {
Request r1 = (Request)outstandingRequests.get(i);
Request r1 = outstandingRequests.get(i);
int j = getFirstOutstandingRequest(r1.piece);
if (j == -1)
continue;
Request r2 = (Request)outstandingRequests.get(j);
Request r2 = outstandingRequests.get(j);
if (r2.off > 0 && ((req == null) || (r2.off > req.off)))
req = r2;
}
@@ -387,7 +395,7 @@ class PeerState
}
Request req = null;
for (int i = 0; i < size; i++) {
Request r1 = (Request)outstandingRequests.get(i);
Request r1 = outstandingRequests.get(i);
if (pc != r1.piece) {
pc = r1.piece;
arr[pos++] = pc;
@@ -412,32 +420,19 @@ class PeerState
+ " length: " + bs.length);
}
/**
* We now have this piece.
* Tell the peer and cancel any requests for the piece.
*/
void havePiece(int piece)
{
if (_log.shouldLog(Log.DEBUG))
_log.debug("Tell " + peer + " havePiece(" + piece + ")");
synchronized(this)
{
// Tell the other side that we are no longer interested in any of
// the outstanding requests for this piece.
if (lastRequest != null && lastRequest.piece == piece)
lastRequest = null;
Iterator it = outstandingRequests.iterator();
while (it.hasNext())
{
Request req = (Request)it.next();
if (req.piece == piece)
{
it.remove();
// Send cancel even when we are choked to make sure that it is
// really never ever send.
out.sendCancel(req);
}
}
}
cancelPiece(piece);
// Tell the other side that we really have this piece.
out.sendHave(piece);
@@ -452,8 +447,46 @@ class PeerState
}
}
// Starts or resumes requesting pieces.
private void request()
/**
* Tell the other side that we are no longer interested in any of
* the outstanding requests (if any) for this piece.
* @since 0.8.1
*/
synchronized void cancelPiece(int piece) {
if (lastRequest != null && lastRequest.piece == piece)
lastRequest = null;
Iterator<Request> it = outstandingRequests.iterator();
while (it.hasNext())
{
Request req = it.next();
if (req.piece == piece)
{
it.remove();
// Send cancel even when we are choked to make sure that it is
// really never ever send.
out.sendCancel(req);
}
}
}
/**
* Are we currently requesting the piece?
* @since 0.8.1
*/
synchronized boolean isRequesting(int piece) {
for (Request req : outstandingRequests) {
if (req.piece == piece)
return true;
}
return false;
}
/**
* Starts or resumes requesting pieces.
* @param resend should we resend outstanding requests?
*/
private void request(boolean resend)
{
// Are there outstanding requests that have to be resend?
if (resend)
@@ -461,7 +494,6 @@ class PeerState
synchronized (this) {
out.sendRequests(outstandingRequests);
}
resend = false;
}
// Add/Send some more requests if necessary.
@@ -470,8 +502,11 @@ class PeerState
/**
* Adds a new request to the outstanding requests list.
* Then send interested if we weren't.
* Then send new requests if not choked.
* If nothing to request, send not interested if we were.
*/
synchronized private void addRequest()
synchronized void addRequest()
{
boolean more_pieces = true;
while (more_pieces)
@@ -512,8 +547,11 @@ class PeerState
_log.debug(peer + " requests " + outstandingRequests);
}
// Starts requesting first chunk of next piece. Returns true if
// something has been added to the requests, false otherwise.
/**
* Starts requesting first chunk of next piece. Returns true if
* something has been added to the requests, false otherwise.
* Caller should synchronize.
*/
private boolean requestNextPiece()
{
// Check that we already know what the other side has.
@@ -540,11 +578,19 @@ class PeerState
}
}
int nextPiece = listener.wantPiece(peer, bitfield);
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " want piece " + nextPiece);
if (nextPiece != -1
&& (lastRequest == null || lastRequest.piece != nextPiece))
{
if (nextPiece != -1
&& (lastRequest == null || lastRequest.piece != nextPiece)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " want piece " + nextPiece);
// Fail safe to make sure we are interested
// When we transition into the end game we may not be interested...
if (!interesting) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " transition to end game, setting interesting");
interesting = true;
out.sendInterest(true);
}
int piece_length = metainfo.getPieceLength(nextPiece);
//Catch a common place for OOMs esp. on 1MB pieces
byte[] bs;
@@ -562,9 +608,25 @@ class PeerState
out.sendRequest(req);
lastRequest = req;
return true;
}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug(peer + " no more pieces to request");
}
}
// failsafe
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;
}
@@ -579,7 +641,7 @@ class PeerState
out.sendInterest(interest);
if (interesting && !choked)
request();
request(true); // we shouldnt have any pending requests, but if we do, resend them
}
}
@@ -605,4 +667,16 @@ class PeerState
if (interesting && !choked)
out.retransmitRequests(outstandingRequests);
}
/**
* debug
* @return string or null
* @since 0.8.1
*/
synchronized String getRequests() {
if (outstandingRequests.isEmpty())
return null;
else
return outstandingRequests.toString();
}
}

View File

@@ -1,22 +1,31 @@
package org.klomp.snark;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import net.i2p.util.ConcurrentHashSet;
public class Piece implements Comparable {
private int id;
private Set peers;
private Set<PeerID> peers;
private boolean requested;
/** @since 0.8.1 */
private int priority;
public Piece(int id) {
this.id = id;
this.peers = Collections.synchronizedSet(new HashSet());
this.requested = false;
this.peers = new ConcurrentHashSet();
}
/**
* Highest priority first,
* then rarest first
*/
public int compareTo(Object o) throws ClassCastException {
int pdiff = ((Piece)o).priority - this.priority; // reverse
if (pdiff != 0)
return pdiff;
return this.peers.size() - ((Piece)o).peers.size();
}
@@ -37,12 +46,25 @@ public class Piece implements Comparable {
}
public int getId() { return this.id; }
public Set getPeers() { return this.peers; }
/** @deprecated unused */
public Set<PeerID> getPeers() { return this.peers; }
public boolean addPeer(Peer peer) { return this.peers.add(peer.getPeerID()); }
public boolean removePeer(Peer peer) { return this.peers.remove(peer.getPeerID()); }
public boolean isRequested() { return this.requested; }
public void setRequested(boolean requested) { this.requested = requested; }
/** @return default 0 @since 0.8.1 */
public int getPriority() { return this.priority; }
/** @since 0.8.1 */
public void setPriority(int p) { this.priority = p; }
/** @since 0.8.1 */
public boolean isDisabled() { return this.priority < 0; }
/** @since 0.8.1 */
public void setDisabled() { this.priority = -1; }
@Override
public String toString() {
return String.valueOf(id);

View File

@@ -321,7 +321,7 @@ public class Snark
// sixteen random bytes.
byte snark = (((3 + 7 + 10) * (1000 - 8)) / 992) - 17;
id = new byte[20];
Random random = new Random();
Random random = I2PAppContext.getGlobalContext().random();
int i;
for (i = 0; i < 9; i++)
id[i] = 0;
@@ -437,7 +437,7 @@ public class Snark
try { storage.close(); } catch (IOException ioee) {
ioee.printStackTrace();
}
fatal("Could not create storage", ioe);
fatal("Could not check or create storage", ioe);
}
}
@@ -618,14 +618,14 @@ public class Snark
command_interpreter = false;
i++;
}
else if (args[i].equals("--eepproxy"))
{
String proxyHost = args[i+1];
String proxyPort = args[i+2];
if (!configured)
util.setProxy(proxyHost, Integer.parseInt(proxyPort));
i += 3;
}
//else if (args[i].equals("--eepproxy"))
// {
// String proxyHost = args[i+1];
// String proxyPort = args[i+2];
// if (!configured)
// util.setProxy(proxyHost, Integer.parseInt(proxyPort));
// i += 3;
// }
else if (args[i].equals("--i2cp"))
{
String i2cpHost = args[i+1];
@@ -734,7 +734,7 @@ public class Snark
//if (debug >= INFO && t != null)
// t.printStackTrace();
stopTorrent();
throw new RuntimeException("die bart die");
throw new RuntimeException(s + (t == null ? "" : ": " + t));
}
/**

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,8 @@ public class Storage
private Object[] RAFlock; // lock on RAF access
private long[] RAFtime; // when was RAF last accessed, or 0 if closed
private File[] RAFfile; // File to make it easier to reopen
/** priorities by file; default 0; may be null. @since 0.8.1 */
private int[] priorities;
private final StorageListener listener;
private I2PSnarkUtil _util;
@@ -228,6 +230,8 @@ public class Storage
RAFlock = new Object[size];
RAFtime = new long[size];
RAFfile = new File[size];
priorities = new int[size];
int i = 0;
Iterator it = files.iterator();
@@ -286,6 +290,146 @@ public class Storage
return needed == 0;
}
/**
* @param file canonical path (non-directory)
* @return number of bytes remaining; -1 if unknown file
* @since 0.7.14
*/
public long remaining(String file) {
long bytes = 0;
for (int i = 0; i < rafs.length; i++) {
File f = RAFfile[i];
// use canonical in case snark dir or sub dirs are symlinked
String canonical = null;
if (f != null) {
try {
canonical = f.getCanonicalPath();
} catch (IOException ioe) {
f = null;
}
}
if (f != null && canonical.equals(file)) {
if (complete())
return 0;
int psz = metainfo.getPieceLength(0);
long start = bytes;
long end = start + lengths[i];
int pc = (int) (bytes / psz);
long rv = 0;
if (!bitfield.get(pc))
rv = Math.min(psz - (start % psz), lengths[i]);
int pieces = metainfo.getPieces();
for (int j = pc + 1; (((long)j) * psz) < end && j < pieces; j++) {
if (!bitfield.get(j)) {
if (((long)(j+1))*psz < end)
rv += psz;
else
rv += end - (((long)j) * psz);
}
}
return rv;
}
bytes += lengths[i];
}
return -1;
}
/**
* @param file canonical path (non-directory)
* @since 0.8.1
*/
public int getPriority(String file) {
if (complete() || metainfo.getFiles() == null || priorities == null)
return 0;
for (int i = 0; i < rafs.length; i++) {
File f = RAFfile[i];
// use canonical in case snark dir or sub dirs are symlinked
if (f != null) {
try {
String canonical = f.getCanonicalPath();
if (canonical.equals(file))
return priorities[i];
} catch (IOException ioe) {}
}
}
return 0;
}
/**
* Must call setPiecePriorities() after calling this
* @param file canonical path (non-directory)
* @param pri default 0; <0 to disable
* @since 0.8.1
*/
public void setPriority(String file, int pri) {
if (complete() || metainfo.getFiles() == null || priorities == null)
return;
for (int i = 0; i < rafs.length; i++) {
File f = RAFfile[i];
// use canonical in case snark dir or sub dirs are symlinked
if (f != null) {
try {
String canonical = f.getCanonicalPath();
if (canonical.equals(file)) {
priorities[i] = pri;
return;
}
} catch (IOException ioe) {}
}
}
}
/**
* Get the file priorities array.
* @return null on error, if complete, or if only one file
* @since 0.8.1
*/
public int[] getFilePriorities() {
return priorities;
}
/**
* Set the file priorities array.
* Only call this when stopped, but after check()
* @param p may be null
* @since 0.8.1
*/
void setFilePriorities(int[] p) {
priorities = p;
}
/**
* Call setPriority() for all changed files first,
* then call this.
* Set the piece priority to the highest priority
* of all files spanning the piece.
* Caller must pass array to the PeerCoordinator.
* @return null on error, if complete, or if only one file
* @since 0.8.1
*/
public int[] getPiecePriorities() {
if (complete() || metainfo.getFiles() == null || priorities == null)
return null;
int[] rv = new int[metainfo.getPieces()];
int file = 0;
long pcEnd = -1;
long fileEnd = lengths[0] - 1;
int psz = metainfo.getPieceLength(0);
for (int i = 0; i < rv.length; i++) {
pcEnd += psz;
int pri = priorities[file];
while (fileEnd <= pcEnd && file < lengths.length - 1) {
file++;
long oldFileEnd = fileEnd;
fileEnd += lengths[file];
if (priorities[file] > pri && oldFileEnd < pcEnd)
pri = priorities[file];
}
rv[i] = pri;
}
return rv;
}
/**
* The BitField that tells which pieces this storage contains.
* Do not change this since this is the current state of the storage.
@@ -295,6 +439,18 @@ public class Storage
return bitfield;
}
/**
* The base file or directory name of the data,
* as specified in the .torrent file, but filtered to remove
* illegal characters. This is where the data actually is,
* relative to the snark base dir.
*
* @since 0.7.14
*/
public String getBaseName() {
return filterName(metainfo.getName());
}
/**
* Creates (and/or checks) all files from the metainfo file list.
*/
@@ -380,10 +536,14 @@ public class Storage
changed = true;
checkCreateFiles();
}
if (complete())
if (complete()) {
_util.debug("Torrent is complete", Snark.NOTICE);
else
} else {
// fixme saved priorities
if (files != null)
priorities = new int[files.size()];
_util.debug("Still need " + needed + " out of " + metainfo.getPieces() + " pieces", Snark.NOTICE);
}
}
/**
@@ -420,13 +580,29 @@ public class Storage
}
}
private static final char[] ILLEGAL = new char[] {
'<', '>', ':', '"', '/', '\\', '|', '?', '*',
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
/**
* Removes 'suspicious' characters from the give file name.
* Removes 'suspicious' characters from the given file name.
* http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx
*/
private static String filterName(String name)
{
// XXX - Is this enough?
return name.replace(File.separatorChar, '_');
if (name.equals(".") || name.equals(" "))
return "_";
String rv = name;
if (rv.startsWith("."))
rv = '_' + rv.substring(1);
if (rv.endsWith(".") || rv.endsWith(" "))
rv = rv.substring(0, rv.length() - 1) + '_';
for (int i = 0; i < ILLEGAL.length; i++) {
if (rv.indexOf(ILLEGAL[i]) >= 0)
rv = rv.replace(ILLEGAL[i], '_');
}
return rv;
}
private File createFileFromNames(File base, List names) throws IOException
@@ -493,6 +669,10 @@ public class Storage
changed = true;
synchronized(RAFlock[i]) {
allocateFile(i);
// close as we go so we don't run out of file descriptors
try {
closeRAF(i);
} catch (IOException ioe) {}
}
} else {
_util.debug("File '" + names[i] + "' exists, but has wrong length - repairing corruption", Snark.ERROR);
@@ -501,8 +681,10 @@ public class Storage
synchronized(RAFlock[i]) {
checkRAF(i);
rafs[i].setLength(lengths[i]);
try {
closeRAF(i);
} catch (IOException ioe) {}
}
// will be closed below
}
}
@@ -511,10 +693,25 @@ public class Storage
{
pieces = metainfo.getPieces();
byte[] piece = new byte[metainfo.getPieceLength(0)];
int file = 0;
long fileEnd = lengths[0];
long pieceEnd = 0;
for (int i = 0; i < pieces; i++)
{
int length = getUncheckedPiece(i, piece);
boolean correctHash = metainfo.checkPiece(i, piece, 0, length);
// close as we go so we don't run out of file descriptors
pieceEnd += length;
while (fileEnd <= pieceEnd) {
synchronized(RAFlock[file]) {
try {
closeRAF(file);
} catch (IOException ioe) {}
}
if (++file >= rafs.length)
break;
fileEnd += lengths[file];
}
if (correctHash)
{
bitfield.set(i);
@@ -529,13 +726,14 @@ public class Storage
_probablyComplete = complete();
// close all the files so we don't end up with a zillion open ones;
// we will reopen as needed
for (int i = 0; i < rafs.length; i++) {
synchronized(RAFlock[i]) {
try {
closeRAF(i);
} catch (IOException ioe) {}
}
}
// Now closed above to avoid running out of file descriptors
//for (int i = 0; i < rafs.length; i++) {
// synchronized(RAFlock[i]) {
// try {
// closeRAF(i);
// } catch (IOException ioe) {}
// }
//}
if (listener != null) {
listener.storageAllChecked(this);
@@ -544,6 +742,7 @@ public class Storage
}
}
/** this calls openRAF(); caller must synnchronize and call closeRAF() */
private void allocateFile(int nr) throws IOException
{
// caller synchronized
@@ -552,7 +751,12 @@ public class Storage
// the whole file?
listener.storageCreateFile(this, names[nr], lengths[nr]);
final int ZEROBLOCKSIZE = metainfo.getPieceLength(0);
byte[] zeros = new byte[ZEROBLOCKSIZE];
byte[] zeros;
try {
zeros = new byte[ZEROBLOCKSIZE];
} catch (OutOfMemoryError oom) {
throw new IOException(oom.toString());
}
int i;
for (i = 0; i < lengths[nr]/ZEROBLOCKSIZE; i++)
{
@@ -577,6 +781,9 @@ public class Storage
if (rafs == null) return;
for (int i = 0; i < rafs.length; i++)
{
// if we had an IOE in check(), the RAFlock may be null
if (RAFlock[i] == null)
continue;
try {
synchronized(RAFlock[i]) {
closeRAF(i);

View File

@@ -24,6 +24,8 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -31,6 +33,7 @@ import java.util.List;
import java.util.Random;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
@@ -42,7 +45,7 @@ import net.i2p.util.Log;
*/
public class TrackerClient extends I2PAppThread
{
private static final Log _log = new Log(TrackerClient.class);
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(TrackerClient.class);
private static final String NO_EVENT = "";
private static final String STARTED_EVENT = "started";
private static final String COMPLETED_EVENT = "completed";
@@ -123,13 +126,19 @@ public class TrackerClient extends I2PAppThread
// followed by the secondary open trackers
// It's painful, but try to make sure if an open tracker is also
// the primary tracker, that we don't add it twice.
// todo: check for b32 matches as well
trackers = new ArrayList(2);
trackers.add(new Tracker(meta.getAnnounce(), true));
String primary = meta.getAnnounce();
if (isValidAnnounce(primary)) {
trackers.add(new Tracker(meta.getAnnounce(), true));
} else {
_log.warn("Skipping invalid or non-i2p announce: " + primary);
}
List tlist = _util.getOpenTrackers();
if (tlist != null) {
for (int i = 0; i < tlist.size(); i++) {
String url = (String)tlist.get(i);
if (!url.startsWith("http://")) {
if (!isValidAnnounce(url)) {
_log.error("Bad announce URL: [" + url + "]");
continue;
}
@@ -138,22 +147,29 @@ public class TrackerClient extends I2PAppThread
_log.error("Bad announce URL: [" + url + "]");
continue;
}
if (meta.getAnnounce().startsWith(url.substring(0, slash)))
if (primary.startsWith(url.substring(0, slash)))
continue;
String dest = _util.lookup(url.substring(7, slash));
if (dest == null) {
_log.error("Announce host unknown: [" + url + "]");
_log.error("Announce host unknown: [" + url.substring(7, slash) + "]");
continue;
}
if (meta.getAnnounce().startsWith("http://" + dest))
if (primary.startsWith("http://" + dest))
continue;
if (meta.getAnnounce().startsWith("http://i2p/" + dest))
if (primary.startsWith("http://i2p/" + dest))
continue;
trackers.add(new Tracker(url, false));
_log.debug("Additional announce: [" + url + "] for infoHash: " + infoHash);
}
}
if (tlist.isEmpty()) {
// FIXME really need to get this message to the gui
stop = true;
_log.error("No valid trackers for infoHash: " + infoHash);
return;
}
long uploaded = coordinator.getUploaded();
long downloaded = coordinator.getDownloaded();
long left = coordinator.getLeft();
@@ -167,7 +183,7 @@ public class TrackerClient extends I2PAppThread
boolean runStarted = false;
boolean firstTime = true;
int consecutiveFails = 0;
Random r = new Random();
Random r = I2PAppContext.getGlobalContext().random();
while(!stop)
{
try
@@ -243,17 +259,18 @@ public class TrackerClient extends I2PAppThread
tr.started = true;
Set peers = info.getPeers();
tr.seenPeers = peers.size();
tr.seenPeers = info.getPeerCount();
if (coordinator.trackerSeenPeers < tr.seenPeers) // update rising number quickly
coordinator.trackerSeenPeers = tr.seenPeers;
if ( (left > 0) && (!completed) ) {
// we only want to talk to new people if we need things
// from them (duh)
List ordered = new ArrayList(peers);
Collections.shuffle(ordered);
Collections.shuffle(ordered, r);
Iterator it = ordered.iterator();
while (it.hasNext()) {
while ((!stop) && it.hasNext()) {
Peer cur = (Peer)it.next();
// FIXME if id == us || dest == us continue;
// only delay if we actually make an attempt to add peer
if(coordinator.addPeer(cur)) {
int delay = DELAY_MUL;
@@ -340,7 +357,12 @@ public class TrackerClient extends I2PAppThread
+ "&uploaded=" + uploaded
+ "&downloaded=" + downloaded
+ "&left=" + left
+ "&compact=1" // NOTE: opentracker will return 400 for &compact alone
+ ((! event.equals(NO_EVENT)) ? ("&event=" + event) : "");
if (left <= 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
s += "&numwant=0";
else
s += "&numwant=" + _util.getMaxConnections();
_util.debug("Sending TrackerClient request: " + s, Snark.INFO);
tr.lastRequestTime = System.currentTimeMillis();
@@ -399,7 +421,23 @@ public class TrackerClient extends I2PAppThread
return sb.toString();
}
private class Tracker
/**
* @return true for i2p hosts only
* @since 0.7.12
*/
static boolean isValidAnnounce(String ann) {
URL url;
try {
url = new URL(ann);
} catch (MalformedURLException mue) {
return false;
}
return url.getProtocol().equals("http") &&
(url.getHost().endsWith(".i2p") || url.getHost().equals("i2p")) &&
url.getPort() < 0;
}
private static class Tracker
{
String announce;
boolean isPrimary;

View File

@@ -23,7 +23,7 @@ package org.klomp.snark;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,11 +32,19 @@ import org.klomp.snark.bencode.BDecoder;
import org.klomp.snark.bencode.BEValue;
import org.klomp.snark.bencode.InvalidBEncodingException;
/**
* The data structure for the tracker response.
* Handles both traditional and compact formats.
* Compact format 1 - a list of hashes - early format for testing
* Compact format 2 - One big string of concatenated hashes - official format
*/
public class TrackerInfo
{
private final String failure_reason;
private final int interval;
private final Set peers;
private final Set<Peer> peers;
private int complete;
private int incomplete;
public TrackerInfo(InputStream in, byte[] my_id, MetaInfo metainfo)
throws IOException
@@ -68,40 +76,100 @@ public class TrackerInfo
throw new InvalidBEncodingException("No interval given");
else
interval = beInterval.getInt();
BEValue bePeers = (BEValue)m.get("peers");
if (bePeers == null)
throw new InvalidBEncodingException("No peer list");
else
peers = getPeers(bePeers.getList(), my_id, metainfo);
if (bePeers == null) {
peers = Collections.EMPTY_SET;
} else {
Set<Peer> p;
try {
// One big string (the official compact format)
p = getPeers(bePeers.getBytes(), my_id, metainfo);
} catch (InvalidBEncodingException ibe) {
// List of Dictionaries or List of Strings
p = getPeers(bePeers.getList(), my_id, metainfo);
}
peers = p;
}
BEValue bev = (BEValue)m.get("complete");
if (bev != null) try {
complete = bev.getInt();
if (complete < 0)
complete = 0;
} catch (InvalidBEncodingException ibe) {}
bev = (BEValue)m.get("incomplete");
if (bev != null) try {
incomplete = bev.getInt();
if (incomplete < 0)
incomplete = 0;
} catch (InvalidBEncodingException ibe) {}
}
}
public static Set getPeers(InputStream in, byte[] my_id, MetaInfo metainfo)
/******
public static Set<Peer> getPeers(InputStream in, byte[] my_id, MetaInfo metainfo)
throws IOException
{
return getPeers(new BDecoder(in), my_id, metainfo);
}
public static Set getPeers(BDecoder be, byte[] my_id, MetaInfo metainfo)
public static Set<Peer> getPeers(BDecoder be, byte[] my_id, MetaInfo metainfo)
throws IOException
{
return getPeers(be.bdecodeList().getList(), my_id, metainfo);
}
******/
public static Set getPeers(List l, byte[] my_id, MetaInfo metainfo)
/** List of Dictionaries or List of Strings */
private static Set<Peer> getPeers(List<BEValue> l, byte[] my_id, MetaInfo metainfo)
throws IOException
{
Set peers = new HashSet(l.size());
Set<Peer> peers = new HashSet(l.size());
Iterator it = l.iterator();
while (it.hasNext())
{
for (BEValue bev : l) {
PeerID peerID;
try {
peerID = new PeerID(((BEValue)it.next()).getMap());
// Case 1 - non-compact - A list of dictionaries (maps)
peerID = new PeerID(bev.getMap());
} catch (InvalidBEncodingException ibe) {
// don't let one bad entry spoil the whole list
//Snark.debug("Discarding peer from list: " + ibe, Snark.ERROR);
try {
// Case 2 - compact - A list of 32-byte binary strings (hashes)
// This was just for testing and is not the official format
peerID = new PeerID(bev.getBytes());
} catch (InvalidBEncodingException ibe2) {
// don't let one bad entry spoil the whole list
//Snark.debug("Discarding peer from list: " + ibe, Snark.ERROR);
continue;
}
}
peers.add(new Peer(peerID, my_id, metainfo));
}
return peers;
}
private static final int HASH_LENGTH = 32;
/**
* One big string of concatenated 32-byte hashes
* @since 0.8.1
*/
private static Set<Peer> getPeers(byte[] l, byte[] my_id, MetaInfo metainfo)
throws IOException
{
int count = l.length / HASH_LENGTH;
Set<Peer> peers = new HashSet(count);
for (int i = 0; i < count; i++) {
PeerID peerID;
byte[] hash = new byte[HASH_LENGTH];
System.arraycopy(l, i * HASH_LENGTH, hash, 0, HASH_LENGTH);
try {
peerID = new PeerID(hash);
} catch (InvalidBEncodingException ibe) {
// won't happen
continue;
}
peers.add(new Peer(peerID, my_id, metainfo));
@@ -110,11 +178,17 @@ public class TrackerInfo
return peers;
}
public Set getPeers()
public Set<Peer> getPeers()
{
return peers;
}
public int getPeerCount()
{
int pc = peers == null ? 0 : peers.size();
return Math.max(pc, complete + incomplete - 1);
}
public String getFailureReason()
{
return failure_reason;
@@ -132,6 +206,8 @@ public class TrackerInfo
return "TrackerInfo[FAILED: " + failure_reason + "]";
else
return "TrackerInfo[interval=" + interval
+ (complete > 0 ? (", complete=" + complete) : "" )
+ (incomplete > 0 ? (", incomplete=" + incomplete) : "" )
+ ", peers=" + peers + "]";
}
}

View File

@@ -279,7 +279,9 @@ public class BDecoder
public BEValue bdecodeMap() throws IOException
{
int c = getNextIndicator();
if (c != 'd')
if (c == '<')
throw new InvalidBEncodingException("Expected a .torrent metainfo file but found HTML? Check URL or file!");
else if (c != 'd')
throw new InvalidBEncodingException("Expected 'd', not '"
+ (char)c + "'");
indicator = 0;

View File

@@ -140,7 +140,7 @@ public class BEValue
* succeeds when the BEValue is actually a List, otherwise it will
* throw a InvalidBEncodingException.
*/
public List getList() throws InvalidBEncodingException
public List<BEValue> getList() throws InvalidBEncodingException
{
try
{
@@ -157,7 +157,7 @@ public class BEValue
* values. This operation only succeeds when the BEValue is actually
* a Map, otherwise it will throw a InvalidBEncodingException.
*/
public Map getMap() throws InvalidBEncodingException
public Map<BEValue, BEValue> getMap() throws InvalidBEncodingException
{
try
{
@@ -179,7 +179,7 @@ public class BEValue
if (value instanceof byte[])
{
byte[] bs = (byte[])value;
// XXX - Stupid heuristic...
// XXX - Stupid heuristic... and not UTF-8
if (bs.length <= 12)
valueString = new String(bs);
else

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,844 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2psnark package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
# foo <foo@bar>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: I2P i2psnark\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-11-13 08:01+0000\n"
"PO-Revision-Date: 2010-11-13 20:35+0100\n"
"Last-Translator: mixxy <m1xxy@mail.i2p>\n"
"Language-Team: foo <foo@bar>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: French\n"
#: ../java/src/org/klomp/snark/SnarkManager.java:90
#, java-format
msgid "Adding torrents in {0} minutes"
msgstr "Ajouter des torrents dans {0} minutes"
#: ../java/src/org/klomp/snark/SnarkManager.java:261
#, java-format
msgid "Total uploaders limit changed to {0}"
msgstr "Limite agrégée des uploaders modifiée : {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:263
#, java-format
msgid "Minimum total uploaders limit is {0}"
msgstr "La limite minimale agrégée des uploaders est : {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:275
#, java-format
msgid "Up BW limit changed to {0}KBps"
msgstr "La limite d'upload modifiée : {0} Ko/s"
#: ../java/src/org/klomp/snark/SnarkManager.java:277
#, java-format
msgid "Minimum up bandwidth limit is {0}KBps"
msgstr "La limite minimale d'upload est {0} Ko/s"
#: ../java/src/org/klomp/snark/SnarkManager.java:289
#, java-format
msgid "Startup delay limit changed to {0} minutes"
msgstr "Delais de démarrage modifié : {0] minutes"
#: ../java/src/org/klomp/snark/SnarkManager.java:336
msgid "I2CP and tunnel changes will take effect after stopping all torrents"
msgstr "Les modifications I2CP et des tunnels seront prise en compte après avoir arrêté tous les torrents"
#: ../java/src/org/klomp/snark/SnarkManager.java:343
msgid "Disconnecting old I2CP destination"
msgstr "Déconnexion des anciennes destination I2CP"
#: ../java/src/org/klomp/snark/SnarkManager.java:347
#, java-format
msgid "I2CP settings changed to {0}"
msgstr "Les paramètres I2CP ont été changés : {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:351
msgid "Unable to connect with the new settings, reverting to the old I2CP settings"
msgstr "Impossible de se connecter avec les nouveaux paramètres, retour à l'ancienne configuration I2CP"
#: ../java/src/org/klomp/snark/SnarkManager.java:355
msgid "Unable to reconnect with the old settings!"
msgstr "Impossible de se reconnecter avec les anciens paramètres!"
#: ../java/src/org/klomp/snark/SnarkManager.java:357
msgid "Reconnected on the new I2CP destination"
msgstr "Reconnexion sur la nouvelle destination I2CP"
#: ../java/src/org/klomp/snark/SnarkManager.java:368
#, java-format
msgid "I2CP listener restarted for \"{0}\""
msgstr "Listener I2CP redémarré pour \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:379
msgid "Enabled autostart"
msgstr "Le démarrage automatique est activé"
#: ../java/src/org/klomp/snark/SnarkManager.java:381
msgid "Disabled autostart"
msgstr "Le démarrage automatique est désactivé"
#: ../java/src/org/klomp/snark/SnarkManager.java:387
msgid "Enabled open trackers - torrent restart required to take effect."
msgstr "Les open trackers sont activés - ceci a nécessité un redémarrage des torrents pour être pris en compte."
#: ../java/src/org/klomp/snark/SnarkManager.java:389
msgid "Disabled open trackers - torrent restart required to take effect."
msgstr "Les open trackers sont désactivés - ceci a nécessité un redémarrage des torrents pour être pris en compte."
#: ../java/src/org/klomp/snark/SnarkManager.java:396
msgid "Open Tracker list changed - torrent restart required to take effect."
msgstr "Liste des Open trackers modifiée - ceci nécessite un redémarrage des torrents pour être pris en compte"
#: ../java/src/org/klomp/snark/SnarkManager.java:403
msgid "Configuration unchanged."
msgstr "La configuration n'a pas été modifiée"
#: ../java/src/org/klomp/snark/SnarkManager.java:413
#, java-format
msgid "Unable to save the config to {0}"
msgstr "Impossible de sauvegarder la configuration vers {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:452
msgid "Connecting to I2P"
msgstr "Connexion à I2P"
#: ../java/src/org/klomp/snark/SnarkManager.java:455
msgid "Error connecting to I2P - check your I2CP settings!"
msgstr "Erreur de connexion à I2P - Vérifiez vos paramètres I2CP!"
#: ../java/src/org/klomp/snark/SnarkManager.java:464
#, java-format
msgid "Error: Could not add the torrent {0}"
msgstr "Erreur : Impossible d'ajouter le torrent : {0}"
#. catch this here so we don't try do delete it below
#: ../java/src/org/klomp/snark/SnarkManager.java:486
#, java-format
msgid "Cannot open \"{0}\""
msgstr "Impossible d'ouvrir: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:499
#, java-format
msgid "Warning - Ignoring non-i2p tracker in \"{0}\", will announce to i2p open trackers only"
msgstr "Attention - Les trackers non-i2p dans \"{0}\" sont ignorés, seuls les open trackers I2P seront utilisés!"
#: ../java/src/org/klomp/snark/SnarkManager.java:501
#, java-format
msgid "Warning - Ignoring non-i2p tracker in \"{0}\", and open trackers are disabled, you must enable open trackers before starting the torrent!"
msgstr "Attention - Les trackers non-i2p dans \"{0}\" sont ignorés, et les open trackers sont désactivés, vous devez activer les open trackers avant de démarrer le torrent!"
#: ../java/src/org/klomp/snark/SnarkManager.java:521
#, java-format
msgid "Torrent in \"{0}\" is invalid"
msgstr "Le torrent dans \"{0}\" est invalide"
#: ../java/src/org/klomp/snark/SnarkManager.java:536
#, java-format
msgid "Torrent added and started: \"{0}\""
msgstr "Torrent ajouté et démarré: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:538
#, java-format
msgid "Torrent added: \"{0}\""
msgstr "Torrent ajouté: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:692
#, java-format
msgid "Too many files in \"{0}\" ({1}), deleting it!"
msgstr "Trop de fichiers dans \"{0}\" ({1}), suppression! "
#: ../java/src/org/klomp/snark/SnarkManager.java:694
#, java-format
msgid "Torrent file \"{0}\" cannot end in \".torrent\", deleting it!"
msgstr "Le fichier torrent \"{0}\" ne peut pas se terminer par \".torrent\", suppression!"
#: ../java/src/org/klomp/snark/SnarkManager.java:696
#, java-format
msgid "No pieces in \"{0}\", deleting it!"
msgstr "Pas de morceaux dans \"{0}\", suppression!"
#: ../java/src/org/klomp/snark/SnarkManager.java:698
#, java-format
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
msgstr "Trop de morceaux dans \"{0}\" , la limite est {1}, suppression!"
#: ../java/src/org/klomp/snark/SnarkManager.java:700
#, java-format
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
msgstr "Les morceaux sont trop larges dans \"{0}\" ({1}B), suppresion."
#: ../java/src/org/klomp/snark/SnarkManager.java:701
#, java-format
msgid "Limit is {0}B"
msgstr "La limite est de \"{0}\"Octets"
#: ../java/src/org/klomp/snark/SnarkManager.java:709
#, java-format
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
msgstr "Les torrents dont la taille est supérieure à \"{0}\"Octets ne sont pas encore supportés, suppression \"{1}\"."
#: ../java/src/org/klomp/snark/SnarkManager.java:725
#, java-format
msgid "Error: Could not remove the torrent {0}"
msgstr "Erreur: Impossible de supprimer le torrent \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:746
#, java-format
msgid "Torrent stopped: \"{0}\""
msgstr "Torrent arrêté:\"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:761
#, java-format
msgid "Torrent removed: \"{0}\""
msgstr "Torrent supprimé:\"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:799
#, java-format
msgid "Download finished: {0}"
msgstr "Téléchargement terminé:\"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:799
#, java-format
msgid "size: {0}B"
msgstr "Taille: {0}Octets"
#: ../java/src/org/klomp/snark/SnarkManager.java:827
msgid "Unable to connect to I2P!"
msgstr "Impossible de se connecter à I2P!"
#: ../java/src/org/klomp/snark/SnarkManager.java:833
#, java-format
msgid "Unable to add {0}"
msgstr "Impossible d'ajouter {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:176
msgid "I2PSnark - Anonymous BitTorrent Client"
msgstr "I2PSnark - Client BitTorrent anonyme"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:187
msgid "Torrents"
msgstr "Torrents"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:190
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:197
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:901
msgid "I2PSnark"
msgstr "I2PSnark"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:194
msgid "Refresh page"
msgstr "Rafraîchir la page"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:199
msgid "Forum"
msgstr "Forum"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:248
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1377
msgid "Status"
msgstr "État"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:255
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:257
msgid "Hide Peers"
msgstr "Cacher les pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:262
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:264
msgid "Show Peers"
msgstr "Afficher les pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:271
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:273
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1358
msgid "Torrent"
msgstr "Torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:276
msgid "Estimated Download Time"
msgstr "Temps estimé de téléchargement"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:278
msgid "ETA"
msgstr "Temps restant"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:281
msgid "Downloaded"
msgstr "Téléchargé"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:283
msgid "RX"
msgstr "Réception"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:286
msgid "Uploaded"
msgstr "Envoyé"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:288
msgid "TX"
msgstr "Transmission"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:291
msgid "Down Rate"
msgstr "Taux de téléchargement"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:293
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:298
msgid "Rate"
msgstr "Vitesse"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:296
msgid "Up Rate"
msgstr "Taux d'envoi"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:304
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:307
msgid "Stop all torrents and the I2P tunnel"
msgstr "Arrêter tous les torrents et le tunnel I2P"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:309
msgid "Stop All"
msgstr "Arrêter tout"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:315
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:318
msgid "Start all torrents and the I2P tunnel"
msgstr "Démarrer tous les torrents et le tunnel I2P"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:336
msgid "No torrents loaded."
msgstr "Aucun torrent chargé."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:341
msgid "Totals"
msgstr "Totaux"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:343
#, java-format
msgid "1 torrent"
msgid_plural "{0} torrents"
msgstr[0] "1 torrent"
msgstr[1] "{0} torrents"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:346
#, java-format
msgid "1 connected peer"
msgid_plural "{0} connected peers"
msgstr[0] "1 pair connecté"
msgstr[1] "{0} pairs connectés"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:375
#, java-format
msgid "Torrent file {0} does not exist"
msgstr "Le fichier torrent {0} n'existe pas"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:385
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1629
#, java-format
msgid "Torrent already running: {0}"
msgstr "Torrent déjà actif: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:387
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1631
#, java-format
msgid "Torrent already in the queue: {0}"
msgstr "Torrent déjà dans la queue: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:391
#, java-format
msgid "Copying torrent to {0}"
msgstr "Copie du torrent vers {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:394
#, java-format
msgid "Unable to copy the torrent to {0}"
msgstr "Impossible de copier le torrent vers {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:394
#, java-format
msgid "from {0}"
msgstr "depuis {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:402
#, java-format
msgid "Fetching {0}"
msgstr "Envoi {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:406
msgid "Invalid URL - must start with http://"
msgstr "URL invalide - elle doit débuter par http://"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:436
#, java-format
msgid "Starting up torrent {0}"
msgstr "Démarrage du torrent {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:456
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:474
#, java-format
msgid "Torrent file deleted: {0}"
msgstr "Fichier torrent effacé: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:480
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:490
#, java-format
msgid "Data file deleted: {0}"
msgstr "Fichier de données effacé: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:482
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:492
#, java-format
msgid "Data file could not be deleted: {0}"
msgstr "Le fichier de données ne peut être effacé: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:501
#, java-format
msgid "Data dir deleted: {0}"
msgstr "Répertoire des données effacé: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:533
msgid "Error creating torrent - you must select a tracker"
msgstr "Erreur lors de la création du torrent - vous devez sélectionner un tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:548
#, java-format
msgid "Torrent created for \"{0}\""
msgstr "Torrent créé pour \"{0}\""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:551
#, java-format
msgid "Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\""
msgstr "De nombreux trackers I2P nécessitent d'enregistrer les nouveaux torrents avant de seeder - faites-le avant de démarrer \"{0}\"!"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
#, java-format
msgid "Error creating a torrent for \"{0}\""
msgstr "Erreur de création du torrent pour \"{0}\""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:556
#, java-format
msgid "Cannot create a torrent for the nonexistent data: {0}"
msgstr "Impossible de créer un torrent pour des données inexistantes: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:559
msgid "Error creating torrent - you must enter a file or directory"
msgstr "Erreur de création du torrent - vous devez saisir un fichier ou un répertoire"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:562
msgid "Stopping all torrents and closing the I2P tunnel."
msgstr "Arrêt de tous les torrents et fermeture du tunnel I2P."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:573
msgid "I2P tunnel closed."
msgstr "Tunnel I2P fermé."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:576
msgid "Opening the I2P tunnel and starting all torrents."
msgstr "Ouverture du tunnel I2P and démarrage de tous les torrents."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:915
msgid "Unknown"
msgstr "Inconnu"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:701
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:706
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:712
msgid "Tracker Error"
msgstr "Erreur du tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:704
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:708
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:720
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:724
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:732
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:736
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:741
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:745
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:749
#, java-format
msgid "1 peer"
msgid_plural "{0} peers"
msgstr[0] "1 pair"
msgstr[1] "{0} pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:717
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:722
msgid "Seeding"
msgstr "Seed en cours"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:726
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1427
msgid "Complete"
msgstr "Complet"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:729
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:734
msgid "Downloading"
msgstr "Téléchargement en cours"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:738
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:743
msgid "Stalled"
msgstr "Figé"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:747
msgid "No Peers"
msgstr "Pas de pair"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:751
msgid "Stopped"
msgstr "Arrêté"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:766
msgid "View files"
msgstr "Voir les fichiers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:768
msgid "Open file"
msgstr "Ouvrir fichier"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:798
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1049
msgid "Tracker"
msgstr "Tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:833
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:836
msgid "Stop the torrent"
msgstr "Arrêter le torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:838
msgid "Stop"
msgstr "Arrêter"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:845
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:848
msgid "Start the torrent"
msgstr "Arrêter le torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:850
msgid "Start"
msgstr "Démarrer"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:856
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:864
msgid "Remove the torrent from the active list, deleting the .torrent file"
msgstr "Enlever le torrent de la liste active, suprression du fichier .torrent"
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
#. Then the remaining single quite must be escaped
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:861
#, java-format
msgid "Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded data will not be deleted) ?"
msgstr "Etes-vous certain de vouloir supprimer le fichier \\''{0}.torrent\\'' (les données déjà téléchargées ne seront pas supprimées) ?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:866
msgid "Remove"
msgstr "Enlever"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:871
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:879
msgid "Delete the .torrent file and the associated data file(s)"
msgstr "Supprimer le fichier .torrent et le(s) fichier(s) de données associé(s)"
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
#. Then the remaining single quite must be escaped
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:876
#, java-format
msgid "Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?"
msgstr "Etes-vous certain de vouloir supprimer le torrent \\''{0}\\'' ainsi que toutes les données téléchargées ?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:881
msgid "Delete"
msgstr "Supprimer"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:925
msgid "Seed"
msgstr "Seed"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:943
msgid "Uninteresting (The peer has no pieces we need)"
msgstr "aucun intérêt (le pair n'a aucun morceau utile)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:945
msgid "Choked (The peer is not allowing us to request pieces)"
msgstr "bridé (le pair ne nous permet pas de demander un morceau)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:959
msgid "Uninterested (We have no pieces the peer needs)"
msgstr "aucun intérêt (nous n'avons aucun morceau utile au pair)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:961
msgid "Choking (We are not allowing the peer to request pieces)"
msgstr "bridage (nous ne permettons pas au pair de demander un morceau)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1005
msgid "Add Torrent"
msgstr "Ajouter torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1007
msgid "From URL"
msgstr "Depuis l'url"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1010
msgid "Torrent file must originate from an I2P-based tracker"
msgstr "Le fichier torrent doit provenir d'un tracker I2P"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1015
msgid "Add torrent"
msgstr "Ajouter torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1018
#, java-format
msgid "You can also copy .torrent files to: {0}."
msgstr "Vous pouvez aussi copier les fichiers .torrent vers {0}."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1020
msgid "Removing a .torrent will cause it to stop."
msgstr "La suppression d'un fichier .torrent entraine l'arrêt du torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1040
msgid "Create Torrent"
msgstr "Créer torrent"
#. out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1043
msgid "Data to seed"
msgstr "Données à seeder"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1047
msgid "File or directory to seed (must be within the specified path)"
msgstr "Fichier ou répertoire à seeder (doit être dans le chemin spécifié)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1051
msgid "Select a tracker"
msgstr "Sélectionner un tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1064
msgid "or"
msgstr "ou"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1067
msgid "Specify custom tracker announce URL"
msgstr "Spécifier une URL personnalisée d'annonce de tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1070
msgid "Create torrent"
msgstr "Créer torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1089
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1213
msgid "Configuration"
msgstr "Configuration"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1092
msgid "Data directory"
msgstr "Répertoire de données"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1094
msgid "Edit i2psnark.config and restart to change"
msgstr "Editez i2psnark.config et redémarrez pour prendre en compte les modifications"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1098
msgid "Auto start"
msgstr "Démarrage automatique"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1102
msgid "If checked, automatically start torrents that are added"
msgstr "Si coché, les torrents démarrerons automatiquement lors de l'ajout"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1106
msgid "Startup delay"
msgstr "Délais de démarrage"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1108
msgid "minutes"
msgstr "minutes"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1132
msgid "Total uploader limit"
msgstr "Limite totale d'envoi"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1135
msgid "peers"
msgstr "pairs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1139
msgid "Up bandwidth limit"
msgstr "Limite de bande passante en envoi"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1142
msgid "Half available bandwidth recommended."
msgstr "La moitié de la bande passante est recommandée."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1144
msgid "View or change router bandwidth"
msgstr "Consulter ou modifier la bande passante du routeur"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1148
msgid "Use open trackers also"
msgstr "Utiliser les open trackers aussi"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1152
msgid "If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"
msgstr "Si coché, les torrents seront annoncés vers les open trackers ainsi que vers les trackers indiqués dans le fichier torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1156
msgid "Open tracker announce URLs"
msgstr "URL d'annonce open tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1168
msgid "Inbound Settings"
msgstr "Paramètres entrants"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1174
msgid "Outbound Settings"
msgstr "Paramètres sortants"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1181
msgid "I2CP host"
msgstr "Hôte I2CP"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1186
msgid "I2CP port"
msgstr "Port I2CP"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1198
msgid "I2CP options"
msgstr "Options I2CP"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1203
msgid "Save configuration"
msgstr "Sauver la configuration"
#. * dummies for translation
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1221
#, java-format
msgid "1 hop"
msgid_plural "{0} hops"
msgstr[0] "1 saut"
msgstr[1] "{0} sauts"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1222
#, java-format
msgid "1 tunnel"
msgid_plural "{0} tunnels"
msgstr[0] "1 tunnel"
msgstr[1] "{0} tunnels"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1371
msgid "File"
msgstr "Fichier"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1374
msgid "FileSize"
msgstr "Taille du fichier"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1374
msgid "Size"
msgstr "Taille"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1377
msgid "Download Status"
msgstr "État du téléchargement"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1381
msgid "Priority"
msgstr "Priorité"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1386
msgid "Up to higher level directory"
msgstr "Vers le répertoire parent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1411
msgid "Directory"
msgstr "Répertoire"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1416
msgid "Torrent not found?"
msgstr "Torrent non trouvé?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1424
msgid "File not found in torrent?"
msgstr "Fichier non trouvé dans le torrent?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1431
msgid "complete"
msgstr "complet"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1432
msgid "bytes remaining"
msgstr "Octets restants"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1483
msgid "High"
msgstr "Haut"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1488
msgid "Normal"
msgstr "Normal"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1493
msgid "Ignore"
msgstr "Ignore"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1502
msgid "Save priorities"
msgstr "Sauver les priorités"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1609
#, java-format
msgid "Torrent fetched from {0}"
msgstr "Torrent envoyé de {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1637
#, java-format
msgid "Torrent at {0} was not valid"
msgstr "Le torrent {0} n'est pas valide"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1642
#, java-format
msgid "Torrent was not retrieved from {0}"
msgstr "Le torrent n'a pas été reçu par {0}"
#~ msgid "Start All"
#~ msgstr "Démarrer tout"
#~ msgid "OK"
#~ msgstr "OK"
#~ msgid "Details"
#~ msgstr "Détails"
#~ msgid "Depuis l'URL"
#~ msgstr "Quell-URL"
#~ msgid "Directory to store torrents and data"
#~ msgstr "Répertoire de stockage des torrents et des données"
#~ msgid "Cannot change the I2CP settings while torrents are active"
#~ msgstr "On ne peut changer les paramètres I2CP pendant que des torrents sont actifs"
#~ msgid "Non-i2p tracker in \"{0}\", deleting it from our list of trackers!"
#~ msgstr "Tracker non-i2p dans \"{0}\", suppression de notre liste de trackers!"
#~ msgid "{0} torrents"
#~ msgstr "{0} Torrents"
#~ msgid "Uninteresting"
#~ msgstr "Pas intéressant"
#~ msgid "Choked"
#~ msgstr "Choked"
#~ msgid "Uninterested"
#~ msgstr "Pas interessé"
#~ msgid "Choking"
#~ msgstr "Choking"
#~ msgid "Custom tracker URL"
#~ msgstr "URL tracker spécifique"
#~ msgid "Configure"
#~ msgstr "Configurer"

View File

@@ -0,0 +1,775 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2psnark package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
# foo <foo@bar>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: I2P i2psnark\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-07-05 11:48+0000\n"
"PO-Revision-Date: 2010-06-15 09:07+0100\n"
"Last-Translator: duck <duck@mail.i2p>\n"
"Language-Team: duck <duck@mail.i2p>, monkeybrains <monkeybrains@mail.i2p>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Dutch\n"
#: ../java/src/org/klomp/snark/SnarkManager.java:88
#, java-format
msgid "Adding torrents in {0} minutes"
msgstr "Torrents toevoegen in {0} minuten"
#: ../java/src/org/klomp/snark/SnarkManager.java:258
#, java-format
msgid "Total uploaders limit changed to {0}"
msgstr "Totale uploaders limiet gewijzigd in {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:260
#, java-format
msgid "Minimum total uploaders limit is {0}"
msgstr "Minimum totale uploaders limiet is {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:272
#, java-format
msgid "Up BW limit changed to {0}KBps"
msgstr "Up bandbreedte limiet gewijzigd in {0}KBps"
#: ../java/src/org/klomp/snark/SnarkManager.java:274
#, java-format
msgid "Minimum up bandwidth limit is {0}KBps"
msgstr "Minimum up bandbreedte limiet is {0}KBps"
#: ../java/src/org/klomp/snark/SnarkManager.java:286
#, java-format
msgid "Startup delay limit changed to {0} minutes"
msgstr "Startup vertragings limiet gewijzigd in {0} minuten"
#: ../java/src/org/klomp/snark/SnarkManager.java:333
msgid "I2CP and tunnel changes will take effect after stopping all torrents"
msgstr "I2CP en tunnel wijzigingen hebben pas effect na het stoppen van alle torrents"
#: ../java/src/org/klomp/snark/SnarkManager.java:339
msgid "Disconnecting old I2CP destination"
msgstr "Oude I2CP destination wordt afgesloten"
#: ../java/src/org/klomp/snark/SnarkManager.java:343
#, java-format
msgid "I2CP settings changed to {0}"
msgstr "I2CP instellingen gewijzigd in {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:347
msgid ""
"Unable to connect with the new settings, reverting to the old I2CP settings"
msgstr "Kan geen connectie maken met de nieuwe instellingen, we keren terug naar oude I2CP instellingen"
#: ../java/src/org/klomp/snark/SnarkManager.java:351
msgid "Unable to reconnect with the old settings!"
msgstr "Kan niet opnieuw verbinden met de oude instellingen!"
#: ../java/src/org/klomp/snark/SnarkManager.java:353
msgid "Reconnected on the new I2CP destination"
msgstr "Opnieuw verbonden met de nieuwe I2CP destination"
#: ../java/src/org/klomp/snark/SnarkManager.java:364
#, java-format
msgid "I2CP listener restarted for \"{0}\""
msgstr "I2CP listener herstart voor \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:375
msgid "Enabled autostart"
msgstr "Autostart ingeschakeld"
#: ../java/src/org/klomp/snark/SnarkManager.java:377
msgid "Disabled autostart"
msgstr "Autostart uitgeschakeld"
#: ../java/src/org/klomp/snark/SnarkManager.java:383
msgid "Enabled open trackers - torrent restart required to take effect."
msgstr "Open Trackers ingeschakeld - torrent herstart nodig."
#: ../java/src/org/klomp/snark/SnarkManager.java:385
msgid "Disabled open trackers - torrent restart required to take effect."
msgstr "Open Trackers uitgeschakeld - torrent herstart nodig."
#: ../java/src/org/klomp/snark/SnarkManager.java:392
msgid "Open Tracker list changed - torrent restart required to take effect."
msgstr "Open Tracker lijst gewijzigd - torrent herstart nodig."
#: ../java/src/org/klomp/snark/SnarkManager.java:399
msgid "Configuration unchanged."
msgstr "Configuratie ongewijzigd."
#: ../java/src/org/klomp/snark/SnarkManager.java:409
#, java-format
msgid "Unable to save the config to {0}"
msgstr "Kan de configuratie niet opslaan in {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:445
msgid "Connecting to I2P"
msgstr "Verbinden met I2P"
#: ../java/src/org/klomp/snark/SnarkManager.java:448
msgid "Error connecting to I2P - check your I2CP settings!"
msgstr "Fout bij verbinden met I2P - controlleer je I2CP instellingen!"
#: ../java/src/org/klomp/snark/SnarkManager.java:457
#, java-format
msgid "Error: Could not add the torrent {0}"
msgstr "Fout: Kan de torrent {0} niet toevoegen"
#. catch this here so we don't try do delete it below
#: ../java/src/org/klomp/snark/SnarkManager.java:479
#, java-format
msgid "Cannot open \"{0}\""
msgstr "Kan \"{0}\" niet openen"
#: ../java/src/org/klomp/snark/SnarkManager.java:492
#, java-format
msgid ""
"Warning - Ignoring non-i2p tracker in \"{0}\", will announce to i2p open "
"trackers only"
msgstr "Waarschuwing - Niet-I2P tracker in \"{0}\" wordt genegeerd, zal alleen aankondigen naar i2p open trackers"
#: ../java/src/org/klomp/snark/SnarkManager.java:494
#, java-format
msgid ""
"Warning - Ignoring non-i2p tracker in \"{0}\", and open trackers are "
"disabled, you must enable open trackers before starting the torrent!"
msgstr "Waarschuwing - Niet-I2P tracker in \"{0}\" wordt genegeerd, en open trackers zijn uitgeschakeld, je moet open trackers inschakelen voor het starten van de torrent!"
#: ../java/src/org/klomp/snark/SnarkManager.java:513
#, java-format
msgid "Torrent in \"{0}\" is invalid"
msgstr "Torrent in \"{0}\" is ongeldig"
#: ../java/src/org/klomp/snark/SnarkManager.java:528
#, java-format
msgid "Torrent added and started: \"{0}\""
msgstr "Torrent toegevoegd en gestart: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:530
#, java-format
msgid "Torrent added: \"{0}\""
msgstr "Torrent toegevoegd: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:627
#, java-format
msgid "Too many files in \"{0}\" ({1}), deleting it!"
msgstr "Te veel bestanden in \"{0}\" ({1}), wordt verwijderd!"
#: ../java/src/org/klomp/snark/SnarkManager.java:629
#, java-format
msgid "Torrent file \"{0}\" cannot end in \".torrent\", deleting it!"
msgstr "Torrent bestand \"{0}\" kan niet eindigen in \".torrent\", wordt verwijderd!"
#: ../java/src/org/klomp/snark/SnarkManager.java:631
#, java-format
msgid "No pieces in \"{0}\", deleting it!"
msgstr "Geen stukken in \"{0}\", wordt verwijderd!"
#: ../java/src/org/klomp/snark/SnarkManager.java:633
#, java-format
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
msgstr "Te veel stukken in \"{0}\", limiet is {1}, wordt verwijderd!"
#: ../java/src/org/klomp/snark/SnarkManager.java:635
#, java-format
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
msgstr "Stukken zijn te groot in \"{0}\" ({1}B), wordt verwijderd."
#: ../java/src/org/klomp/snark/SnarkManager.java:636
#, java-format
msgid "Limit is {0}B"
msgstr "Limiet is {0}B"
#: ../java/src/org/klomp/snark/SnarkManager.java:644
#, java-format
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
msgstr "Torrents groter dan {0}B worden nog niet ondersteund, verwijder \"{1}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:660
#, java-format
msgid "Error: Could not remove the torrent {0}"
msgstr "Fout: Kan de torrent {0} niet verwijderen"
#: ../java/src/org/klomp/snark/SnarkManager.java:681
#, java-format
msgid "Torrent stopped: \"{0}\""
msgstr "Torrent gestopt: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:696
#, java-format
msgid "Torrent removed: \"{0}\""
msgstr "Torrent verwijderd: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:729
#, java-format
msgid "Download finished: \"{0}\""
msgstr "Download gereed: \"{0}\""
#: ../java/src/org/klomp/snark/SnarkManager.java:729
#, java-format
msgid "size: {0}B"
msgstr "grootte: {0}B"
#: ../java/src/org/klomp/snark/SnarkManager.java:757
msgid "Unable to connect to I2P!"
msgstr "Kan niet verbinden met I2P!"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:174
msgid "I2PSnark - Anonymous BitTorrent Client"
msgstr "I2PSnark - Anonieme BitTorrent Client"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:185
msgid "Torrents"
msgstr "Torrents"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:187
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:193
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:837
msgid "I2PSnark"
msgstr "I2PSnark"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:191
msgid "Refresh page"
msgstr "Ververs pagina"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:195
msgid "Forum"
msgstr "Forum"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:240
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1289
msgid "Status"
msgstr "Status"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
msgid "Hide Peers"
msgstr "Verberg Peers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:249
msgid "Show Peers"
msgstr "Toon Peers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:254
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1271
msgid "Torrent"
msgstr "Torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:256
msgid "ETA"
msgstr "ETA"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:258
msgid "Downloaded"
msgstr "Gedownload"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:260
msgid "Uploaded"
msgstr "Geupload"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:262
msgid "Down Rate"
msgstr "Down Snelheid"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:264
msgid "Up Rate"
msgstr "Up Snelheid"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:271
msgid "Stop all torrents and the I2P tunnel"
msgstr "Stop alle torrents en de I2P tunnel"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:273
msgid "Stop All"
msgstr "Stop Alle"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:278
msgid "Start all torrents and the I2P tunnel"
msgstr "Start alle torrents en de I2P tunnel"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:280
msgid "Start All"
msgstr "Start Alle"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:297
msgid "No torrents loaded."
msgstr "Geen torrents geladen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:302
msgid "Totals"
msgstr "Totalen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:304
#, java-format
msgid "1 torrent"
msgid_plural "{0} torrents"
msgstr[0] "1 torrent"
msgstr[1] "{0} torrents"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:307
#, java-format
msgid "1 connected peer"
msgid_plural "{0} connected peers"
msgstr[0] "1 verbonden peer"
msgstr[1] "{0} verbonden peers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:336
#, java-format
msgid "Torrent file {0} does not exist"
msgstr "Torrent bestand {0} bestaat niet"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:346
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1476
#, java-format
msgid "Torrent already running: {0}"
msgstr "Torrent draait al: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:348
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1478
#, java-format
msgid "Torrent already in the queue: {0}"
msgstr "Torrent zit al in de wachtrij: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:352
#, java-format
msgid "Copying torrent to {0}"
msgstr "Kopieer torrent naar {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:355
#, java-format
msgid "Unable to copy the torrent to {0}"
msgstr "Kan de de torrent niet kopieren naar {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:355
#, java-format
msgid "from {0}"
msgstr "van {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:363
#, java-format
msgid "Fetching {0}"
msgstr "Downloaden {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:367
msgid "Invalid URL - must start with http://"
msgstr "Ongeldige URL - moet beginnen met http://"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:397
#, java-format
msgid "Starting up torrent {0}"
msgstr "Starten met torrent {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:417
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:435
#, java-format
msgid "Torrent file deleted: {0}"
msgstr "Torrent bestand verwijderd: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:441
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:451
#, java-format
msgid "Data file deleted: {0}"
msgstr "Data bestand verwijderd: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:443
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:453
#, java-format
msgid "Data file could not be deleted: {0}"
msgstr "Kan data bestand niet verwijderen: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:462
#, java-format
msgid "Data dir deleted: {0}"
msgstr "Data directory verwijderd: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:494
msgid "Error creating torrent - you must select a tracker"
msgstr "Fout bij maken van torrent - je moet een tracker selecteren"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
#, java-format
msgid "Torrent created for \"{0}\""
msgstr "Torrent gemaakt voor \"{0}\""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:512
#, java-format
msgid ""
"Many I2P trackers require you to register new torrents before seeding - "
"please do so before starting \"{0}\""
msgstr "Veel I2P trackers vereisen dat je de nieuwe torrent registreert voor het seeden - "
"doe dit voordat je \"{0}\" start"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:514
#, java-format
msgid "Error creating a torrent for \"{0}\""
msgstr "Fout bij het maken van een torrent voor \"{0}\""
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
#, java-format
msgid "Cannot create a torrent for the nonexistent data: {0}"
msgstr "Kan geen torrent maken voor niet-bestaande data: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:520
msgid "Error creating torrent - you must enter a file or directory"
msgstr "Fout bij het maken van de torrent - je moet een bestand of directory invullen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523
msgid "Stopping all torrents and closing the I2P tunnel."
msgstr "Stoppen van alle torrents en sluiten van I2P tunnel."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:532
msgid "I2P tunnel closed."
msgstr "I2P tunnel gesloten."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:535
msgid "Opening the I2P tunnel and starting all torrents."
msgstr "Openen van de I2P tunnel en starten van alle torrents."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:657
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:851
msgid "Unknown"
msgstr "Onbekend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:660
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:665
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:670
msgid "TrackerErr"
msgstr "TrackerErr"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:663
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:666
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:677
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:688
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:691
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:696
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:699
#, java-format
msgid "1 peer"
msgid_plural "{0} peers"
msgstr[0] "1 peer"
msgstr[1] "{0} peers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:674
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:679
msgid "Seeding"
msgstr "Seeding"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:682
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1327
msgid "Complete"
msgstr "Voltooid"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:685
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:690
msgid "OK"
msgstr "OK"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:693
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
msgid "Stalled"
msgstr "Vastgelopen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:701
msgid "No Peers"
msgstr "Geen Peers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:703
msgid "Stopped"
msgstr "Gestopt"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:718
msgid "View files"
msgstr "Bekijk bestanden"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:720
msgid "Open file"
msgstr "Open bestand"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:750
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
msgid "Tracker"
msgstr "Tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:751
msgid "Details"
msgstr "Details"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:785
msgid "Stop the torrent"
msgstr "Stop de torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:787
msgid "Stop"
msgstr "Stop"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:793
msgid "Start the torrent"
msgstr "Start de torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:795
msgid "Start"
msgstr "Start"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:800
msgid "Remove the torrent from the active list, deleting the .torrent file"
msgstr "Verwijder de torrent van de actieve lijst, het .torrent bestand wordt verwijderd"
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
#. Then the remaining single quite must be escaped
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:805
#, java-format
msgid ""
"Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded "
"data will not be deleted) ?"
msgstr "Weet je zeker dat je het bestand \\''{0}.torrent\\'' wilt verwijderen (gedownloade data zal niet worden verwijderd) ?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:807
msgid "Remove"
msgstr "Weghalen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:811
msgid "Delete the .torrent file and the associated data file(s)"
msgstr "Verwijder het .torrent bestand en de gerelateerde data bestand(en)"
#. Can't figure out how to escape double quotes inside the onclick string.
#. Single quotes in translate strings with parameters must be doubled.
#. Then the remaining single quite must be escaped
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:816
#, java-format
msgid ""
"Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded "
"data?"
msgstr "Weet je zeker dat je de torrent \\''{0}\\'' en alle gedownloade data wilt verwijderen?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:818
msgid "Delete"
msgstr "Verwijderen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:861
msgid "Seed"
msgstr "Seed"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:879
msgid "Uninteresting (The peer has no pieces we need)"
msgstr "Niet interessant (De peer heeft geen stukken die we nodig hebben)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:881
msgid "Choked (The peer is not allowing us to request pieces)"
msgstr "Verstikt (De peer laat ons niet toe om stukken op te vragen)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:895
msgid "Uninterested (We have no pieces the peer needs)"
msgstr "Niet geïnteresseerd (We heben geen stukken die de peer nodig heeft)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:897
msgid "Choking (We are not allowing the peer to request pieces)"
msgstr "Verstikt (We laten de peer niet toe om stukken op te vragen)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:927
msgid "Add Torrent"
msgstr "Torrent Toevoegen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:929
msgid "From URL"
msgstr "Van URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:934
msgid "Add torrent"
msgstr "Torrent toevoegen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:937
#, java-format
msgid "Alternately, you can copy .torrent files to the directory {0}."
msgstr "Als alternatief kan je het .torrent bestand kopieren naar de directory {0}."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:939
msgid "Removing a .torrent file will cause the torrent to stop."
msgstr "Verwijderen van een .torrent bestand zorgt dat de torrent stopt."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:958
msgid "Create Torrent"
msgstr "Creëer Torrent"
#. out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:961
msgid "Data to seed"
msgstr "Data om te seeden"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:965
msgid "File or directory to seed (must be within the specified path)"
msgstr "Bestand of directory om te seeden (moet binnen het gespecificeerde pad zijn)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:969
msgid "Select a tracker"
msgstr "Selecteer een tracker"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:982
msgid "or"
msgstr "of"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:985
msgid "Specify custom tracker announce URL"
msgstr "Specificeer aangepaste tracker aankondigings URL"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:988
msgid "Create torrent"
msgstr "Creëer torrent"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1006
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1133
msgid "Configuration"
msgstr "Configuratie"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1009
msgid "Data directory"
msgstr "Data directory"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1012
msgid "Directory to store torrents and data"
msgstr "Directory om torrents en data op te slaan"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1014
msgid "Edit i2psnark.config and restart to change"
msgstr "Bewerk i2psnark.config en herstart de wijziging"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1018
msgid "Auto start"
msgstr "Auto start"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1022
msgid "If checked, automatically start torrents that are added"
msgstr "Indien aangevinkt, start toegevoegde torrents automatisch"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1026
msgid "Startup delay"
msgstr "Startup vertraging"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1028
msgid "minutes"
msgstr "minuten"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1052
msgid "Total uploader limit"
msgstr "Totale uploader limiet"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1055
msgid "peers"
msgstr "peers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1059
msgid "Up bandwidth limit"
msgstr "Up bandbreedte limiet"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1062
msgid "Half available bandwidth recommended."
msgstr "Helft van beschikbare bandbreedte aanbevolen."
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1064
msgid "View or change router bandwidth"
msgstr "Bekijk of wijzig router bandbreedte"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1068
msgid "Use open trackers also"
msgstr "Gebruik ook open trackers"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1072
msgid ""
"If checked, announce torrents to open trackers as well as the tracker listed "
"in the torrent file"
msgstr "Indien aangevinkt, kondig torrents ook aan bij de tracker uit het torrent bestand"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1076
msgid "Open tracker announce URLs"
msgstr "Open tracker aankondigings URLs"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1088
msgid "Inbound Settings"
msgstr "Inkomende Instellingen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1094
msgid "Outbound Settings"
msgstr "Uitgaande Instellingen"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1101
msgid "I2CP host"
msgstr "I2CP host"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1106
msgid "I2CP port"
msgstr "I2CP poort"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1118
msgid "I2CP options"
msgstr "I2CP opties"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1124
msgid "Save configuration"
msgstr "Configuratie opslaan"
#. * dummies for translation
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1141
#, java-format
msgid "1 hop"
msgid_plural "{0} hops"
msgstr[0] "1 hop"
msgstr[1] "{0} hops"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1142
#, java-format
msgid "1 tunnel"
msgid_plural "{0} tunnels"
msgstr[0] "1 tunnel"
msgstr[1] "{0} tunnels"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1283
msgid "Up to higher level directory"
msgstr "Naar bovenliggende directory"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1288
msgid "File"
msgstr "Bestand"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1288
msgid "Size"
msgstr "Grootte"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1311
msgid "Directory"
msgstr "Directory"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1316
msgid "Torrent not found?"
msgstr "Torrent niet gevonden?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1324
msgid "File not found in torrent?"
msgstr "Bestand niet gevonden in torrent?"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1330
msgid "complete"
msgstr "voltooid"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1331
msgid "bytes remaining"
msgstr "bytes resterend"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1456
#, java-format
msgid "Torrent fetched from {0}"
msgstr "Torrent gedownload van {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1484
#, java-format
msgid "Torrent at {0} was not valid"
msgstr "Torrent op {0} was niet geldig"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1489
#, java-format
msgid "Torrent was not retrieved from {0}"
msgstr "Torrent was niet ontvangen van {0}"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -22,4 +22,68 @@
30
</session-timeout>
</session-config>
<!-- mime types not in mime.properties in the jetty 5.1.15 source -->
<mime-mapping>
<extension>mkv</extension>
<mime-type>video/x-matroska</mime-type>
</mime-mapping>
<mime-mapping>
<extension>wmv</extension>
<mime-type>video/x-ms-wmv</mime-type>
</mime-mapping>
<mime-mapping>
<extension>flv</extension>
<mime-type>video/x-flv</mime-type>
</mime-mapping>
<mime-mapping>
<extension>mp4</extension>
<mime-type>video/mp4</mime-type>
</mime-mapping>
<mime-mapping>
<extension>rar</extension>
<mime-type>application/rar</mime-type>
</mime-mapping>
<mime-mapping>
<extension>7z</extension>
<mime-type>application/x-7z-compressed</mime-type>
</mime-mapping>
<mime-mapping>
<extension>iso</extension>
<mime-type>application/x-iso9660-image</mime-type>
</mime-mapping>
<mime-mapping>
<extension>ico</extension>
<mime-type>image/x-icon</mime-type>
</mime-mapping>
<mime-mapping>
<extension>exe</extension>
<mime-type>application/x-msdos-program</mime-type>
</mime-mapping>
<mime-mapping>
<extension>flac</extension>
<mime-type>audio/flac</mime-type>
</mime-mapping>
<mime-mapping>
<extension>m4a</extension>
<mime-type>audio/mpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>wma</extension>
<mime-type>audio/x-ms-wma</mime-type>
</mime-mapping>
</web-app>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="i2ptunnel">
<target name="all" depends="clean, build" />
<target name="build" depends="builddep, jar" />
<target name="build" depends="builddep, jar, war" />
<target name="builddep">
<ant dir="../../ministreaming/java/" target="build" />
<ant dir="../../jetty/" target="build" />
@@ -34,6 +34,10 @@
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<!-- TODO: Move the web classes from the jar to the war - they are not part of the API
- This will require sponge to rewrite some seedless stuff that uses it.
-->
<target name="jar" depends="builddep, compile">
<jar destfile="./build/i2ptunnel.jar" basedir="./build/obj" includes="**/*.class">
<manifest>
@@ -41,8 +45,6 @@
<attribute name="Class-Path" value="i2p.jar mstreaming.jar" />
</manifest>
</jar>
<ant target="bundle" />
<ant target="war" />
</target>
<target name="bundle" depends="compile, precompilejsp">
@@ -77,13 +79,13 @@
</exec>
</target>
<target name="war" depends="precompilejsp">
<target name="war" depends="precompilejsp, bundle">
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
basedir="../jsp/" excludes="web.xml, **/*.java, *.jsp">
basedir="../jsp/" excludes="web.xml, web-fragment.xml, web-out.xml, **/*.java, *.jsp">
</war>
</target>
<target name="precompilejsp" unless="precompilejsp.uptodate">
<target name="precompilejsp" depends="jar" unless="precompilejsp.uptodate">
<delete dir="../jsp/WEB-INF/" />
<delete file="../jsp/web-fragment.xml" />
<delete file="../jsp/web-out.xml" />

View File

@@ -51,7 +51,7 @@ do
# To start a new translation, copy the header from an old translation to the new .po file,
# then ant distclean updater.
find $JPATHS -name *.java > $TMPFILE
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 --add-comments\
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
-o ${i}t
if [ $? -ne 0 ]

View File

@@ -24,6 +24,9 @@ import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
/**
* This does the transparent gzip decompression on the client side.
* Extended in I2PTunnelHTTPServer to do the compression on the server side.
*
* Simple stream for delivering an HTTP response to
* the client, trivially filtered to make sure "Connection: close"
* is always in the response. Perhaps add transparent handling of the
@@ -33,29 +36,27 @@ import net.i2p.util.Log;
*
*/
class HTTPResponseOutputStream extends FilterOutputStream {
private I2PAppContext _context;
private Log _log;
private ByteCache _cache;
private final I2PAppContext _context;
private final Log _log;
protected ByteArray _headerBuffer;
private boolean _headerWritten;
private byte _buf1[];
private final byte _buf1[];
protected boolean _gzip;
private long _dataWritten;
private InternalGZIPInputStream _in;
private static final int CACHE_SIZE = 8*1024;
private static final ByteCache _cache = ByteCache.getInstance(8, CACHE_SIZE);
// OOM DOS prevention
private static final int MAX_HEADER_SIZE = 64*1024;
public HTTPResponseOutputStream(OutputStream raw) {
super(raw);
_context = I2PAppContext.getGlobalContext();
_context.statManager().createRateStat("i2ptunnel.httpCompressionRatio", "ratio of compressed size to decompressed size after transfer", "I2PTunnel", new long[] { 60*1000, 30*60*1000 });
_context.statManager().createRateStat("i2ptunnel.httpCompressed", "compressed size transferred", "I2PTunnel", new long[] { 60*1000, 30*60*1000 });
_context.statManager().createRateStat("i2ptunnel.httpExpanded", "size transferred after expansion", "I2PTunnel", new long[] { 60*1000, 30*60*1000 });
_context.statManager().createRateStat("i2ptunnel.httpCompressionRatio", "ratio of compressed size to decompressed size after transfer", "I2PTunnel", new long[] { 60*60*1000 });
_context.statManager().createRateStat("i2ptunnel.httpCompressed", "compressed size transferred", "I2PTunnel", new long[] { 60*60*1000 });
_context.statManager().createRateStat("i2ptunnel.httpExpanded", "size transferred after expansion", "I2PTunnel", new long[] { 60*60*1000 });
_log = _context.logManager().getLog(getClass());
_cache = ByteCache.getInstance(8, CACHE_SIZE);
_headerBuffer = _cache.acquire();
_headerWritten = false;
_gzip = false;
_dataWritten = 0;
_buf1 = new byte[1];
}
@@ -96,14 +97,20 @@ class HTTPResponseOutputStream extends FilterOutputStream {
}
}
/** grow (and free) the buffer as necessary */
private void ensureCapacity() {
/**
* grow (and free) the buffer as necessary
* @throws IOException if the headers are too big
*/
private void ensureCapacity() throws IOException {
if (_headerBuffer.getValid() >= MAX_HEADER_SIZE)
throw new IOException("Max header size exceeded: " + MAX_HEADER_SIZE);
if (_headerBuffer.getValid() + 1 >= _headerBuffer.getData().length) {
int newSize = (int)(_headerBuffer.getData().length * 1.5);
ByteArray newBuf = new ByteArray(new byte[newSize]);
System.arraycopy(_headerBuffer.getData(), 0, newBuf.getData(), 0, _headerBuffer.getValid());
newBuf.setValid(_headerBuffer.getValid());
newBuf.setOffset(0);
// if we changed the ByteArray size, don't put it back in the cache
if (_headerBuffer.getData().length == CACHE_SIZE)
_cache.release(_headerBuffer);
_headerBuffer = newBuf;
@@ -124,13 +131,13 @@ class HTTPResponseOutputStream extends FilterOutputStream {
* Tweak that first HTTP response line (HTTP 200 OK, etc)
*
*/
protected String filterResponseLine(String line) {
protected static String filterResponseLine(String line) {
return line;
}
/** we ignore any potential \r, since we trim it on write anyway */
private static final byte NL = '\n';
private boolean isNL(byte b) { return (b == NL); }
private static boolean isNL(byte b) { return (b == NL); }
/** ok, received, now munge & write it */
private void writeHeader() throws IOException {
@@ -219,7 +226,7 @@ class HTTPResponseOutputStream extends FilterOutputStream {
//out.flush();
PipedInputStream pi = new PipedInputStream();
PipedOutputStream po = new PipedOutputStream(pi);
new I2PAppThread(new Pusher(pi, out), "HTTP decompresser").start();
new I2PAppThread(new Pusher(pi, out), "HTTP decompressor").start();
out = po;
}
@@ -231,13 +238,13 @@ class HTTPResponseOutputStream extends FilterOutputStream {
_out = out;
}
public void run() {
OutputStream to = null;
_in = null;
long start = System.currentTimeMillis();
long written = 0;
ByteArray ba = null;
try {
_in = new InternalGZIPInputStream(_inRaw);
byte buf[] = new byte[8192];
ba = _cache.acquire();
byte buf[] = ba.getData();
int read = -1;
while ( (read = _in.read(buf)) != -1) {
if (_log.shouldLog(Log.DEBUG))
@@ -251,6 +258,8 @@ class HTTPResponseOutputStream extends FilterOutputStream {
} catch (IOException ioe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error decompressing: " + written + ", " + (_in != null ? _in.getTotalRead() + "/" + _in.getTotalExpanded() : ""), ioe);
} catch (OutOfMemoryError oom) {
_log.error("OOM in HTTP Decompressor", oom);
} finally {
if (_log.shouldLog(Log.WARN) && (_in != null))
_log.warn("After decompression, written=" + written +
@@ -259,23 +268,27 @@ class HTTPResponseOutputStream extends FilterOutputStream {
+ ", expanded=" + _in.getTotalExpanded() + ", remaining=" + _in.getRemaining()
+ ", finished=" + _in.getFinished()
: ""));
if (ba != null)
_cache.release(ba);
if (_out != null) try {
_out.close();
} catch (IOException ioe) {}
}
long end = System.currentTimeMillis();
double compressed = (_in != null ? _in.getTotalRead() : 0);
double expanded = (_in != null ? _in.getTotalExpanded() : 0);
double ratio = 0;
if (expanded > 0)
ratio = compressed/expanded;
_context.statManager().addRateData("i2ptunnel.httpCompressionRatio", (int)(100d*ratio), end-start);
_context.statManager().addRateData("i2ptunnel.httpCompressed", (long)compressed, end-start);
_context.statManager().addRateData("i2ptunnel.httpExpanded", (long)expanded, end-start);
if (compressed > 0 && expanded > 0) {
// only update the stats if we did something
double ratio = compressed/expanded;
_context.statManager().addRateData("i2ptunnel.httpCompressionRatio", (int)(100d*ratio), 0);
_context.statManager().addRateData("i2ptunnel.httpCompressed", (long)compressed, 0);
_context.statManager().addRateData("i2ptunnel.httpExpanded", (long)expanded, 0);
}
}
}
private class InternalGZIPInputStream extends GZIPInputStream {
/** just a wrapper to provide stats for debugging */
private static class InternalGZIPInputStream extends GZIPInputStream {
public InternalGZIPInputStream(InputStream in) throws IOException {
super(in);
}
@@ -293,6 +306,12 @@ class HTTPResponseOutputStream extends FilterOutputStream {
return 0;
}
}
/**
* From Inflater javadoc:
* Returns the total number of bytes remaining in the input buffer. This can be used to find out
* what bytes still remain in the input buffer after decompression has finished.
*/
public long getRemaining() {
try {
return super.inf.getRemaining();
@@ -318,6 +337,7 @@ class HTTPResponseOutputStream extends FilterOutputStream {
return super.toString() + ": " + _in;
}
/*******
public static void main(String args[]) {
String simple = "HTTP/1.1 200 OK\n" +
"foo: bar\n" +
@@ -367,7 +387,6 @@ class HTTPResponseOutputStream extends FilterOutputStream {
"A:\n" +
"\n";
/* */
test("Simple", simple, true);
test("Filtered", filtered, true);
test("Filtered windows", winfilter, true);
@@ -382,7 +401,6 @@ class HTTPResponseOutputStream extends FilterOutputStream {
test("Invalid (bad headers)", invalid5, true);
test("Invalid (bad headers2)", invalid6, false);
test("Invalid (bad headers3)", invalid7, false);
/* */
}
private static void test(String name, String orig, boolean shouldPass) {
@@ -401,4 +419,5 @@ class HTTPResponseOutputStream extends FilterOutputStream {
System.out.println("Properly fails with " + e.getMessage());
}
}
******/
}

View File

@@ -61,6 +61,7 @@ import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.i2ptunnel.socks.I2PSOCKSIRCTunnel;
import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel;
import net.i2p.i2ptunnel.streamr.StreamrConsumer;
import net.i2p.i2ptunnel.streamr.StreamrProducer;
@@ -68,6 +69,9 @@ import net.i2p.util.EventDispatcher;
import net.i2p.util.EventDispatcherImpl;
import net.i2p.util.Log;
/**
* Todo: Most events are not listened to elsewhere, so error propagation is poor
*/
public class I2PTunnel implements Logging, EventDispatcher {
private Log _log;
private EventDispatcherImpl _event;
@@ -162,7 +166,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
System.out.print("I2PTunnel>");
String cmd = r.readLine();
if (cmd == null) break;
runCommand(cmd, this);
if (cmd.length() <= 0) continue;
try {
runCommand(cmd, this);
} catch (Throwable t) {
t.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
@@ -179,6 +188,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
}
/** @return non-null */
List<I2PSession> getSessions() {
synchronized (_sessions) {
return new ArrayList(_sessions);
@@ -350,6 +360,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {hostname, portNumber, privKeyFilename}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runServer(String args[], Logging l) {
if (args.length == 3) {
@@ -362,7 +373,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("unknown host");
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Error resolving " + args[0] + uhe.getMessage());
}
try {
@@ -371,17 +382,18 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
}
if (portNum <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[1]);
privKeyFile = new File(args[2]);
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getConfigDir(), args[2]);
if (!privKeyFile.canRead()) {
l.log("private key file does not exist");
l.log(getPrefix() + "Private key file does not exist or is not readable: " + args[2]);
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Cannot open private key file " + args[2]);
}
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
@@ -399,6 +411,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
/**
* Same args as runServer
* (we should stop duplicating all this code...)
* @throws IllegalArgumentException on config problem
*/
public void runIrcServer(String args[], Logging l) {
if (args.length == 3) {
@@ -411,7 +424,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("unknown host");
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Error resolving " + args[0] + uhe.getMessage());
}
try {
@@ -420,17 +433,18 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
}
if (portNum <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[1]);
privKeyFile = new File(args[2]);
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getConfigDir(), args[2]);
if (!privKeyFile.canRead()) {
l.log("private key file does not exist");
l.log(getPrefix() + "Private key file does not exist or is not readable: " + args[2]);
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Cannot open private key file " + args[2]);
}
I2PTunnelServer serv = new I2PTunnelIRCServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
@@ -456,6 +470,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {hostname, portNumber, spoofedHost, privKeyFilename}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runHttpServer(String args[], Logging l) {
if (args.length == 4) {
@@ -468,7 +483,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("unknown host");
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Error resolving " + args[0] + uhe.getMessage());
}
try {
@@ -477,8 +492,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
}
if (portNum <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[1]);
String spoofedHost = args[2];
@@ -486,10 +502,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getConfigDir(), args[3]);
if (!privKeyFile.canRead()) {
l.log("private key file does not exist");
l.log(getPrefix() + "Private key file does not exist or is not readable: " + args[3]);
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Cannot open private key file " + args[3]);
}
I2PTunnelHTTPServer serv = new I2PTunnelHTTPServer(serverHost, portNum, privKeyFile, args[3], spoofedHost, l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
@@ -518,6 +534,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {hostname, portNumber, proxyPortNumber, spoofedHost, privKeyFilename}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runHttpBidirServer(String args[], Logging l) {
if (args.length == 5) {
@@ -531,7 +548,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("unknown host");
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Error resolving " + args[0] + uhe.getMessage());
}
try {
@@ -540,7 +557,6 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
}
try {
@@ -549,8 +565,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[2], nfe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
}
if (portNum <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[1]);
if (port2Num <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[2]);
String spoofedHost = args[3];
@@ -558,10 +577,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getConfigDir(), args[4]);
if (!privKeyFile.canRead()) {
l.log("private key file does not exist");
l.log(getPrefix() + "Private key file does not exist or is not readable: " + args[4]);
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[4]);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Cannot open private key file " + args[4]);
}
I2PTunnelHTTPBidirServer serv = new I2PTunnelHTTPBidirServer(serverHost, portNum, port2Num, privKeyFile, args[3], spoofedHost, l, (EventDispatcher) this, this);
@@ -584,12 +603,16 @@ public class I2PTunnel implements Logging, EventDispatcher {
* Run the server pointing at the host and port specified using the private i2p
* destination loaded from the given base64 stream. <p />
*
* Deprecated? Why run a server with a private destination?
* Not available from the war GUI
*
* Sets the event "serverTaskId" = Integer(taskId) after the tunnel has been started (or -1 on error)
* Also sets the event "openServerResult" = "ok" or "error" (displaying "Ready!" on the logger after
* 'ok'). So, success = serverTaskId != -1 and openServerResult = ok.
*
* @param args {hostname, portNumber, privKeyBase64}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runTextServer(String args[], Logging l) {
if (args.length == 3) {
@@ -601,7 +624,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("unknown host");
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
throw new IllegalArgumentException(getPrefix() + "Error resolving " + args[0] + uhe.getMessage());
}
try {
@@ -610,8 +633,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", Integer.valueOf(-1));
return;
}
if (portNum <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[1]);
I2PTunnelServer serv = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
@@ -637,6 +661,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {portNumber, destinationBase64 or "file:filename"[, sharedClient [, privKeyFile]]}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runClient(String args[], Logging l) {
boolean isShared = true;
@@ -650,8 +675,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("clientTaskId", Integer.valueOf(-1));
return;
}
if (portNum <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
I2PTunnelTask task;
ownDest = !isShared;
try {
@@ -665,6 +692,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
_log.error(getPrefix() + "Invalid I2PTunnel config to create a client [" + host + ":"+ port + "]", iae);
l.log("Invalid I2PTunnel configuration [" + host + ":" + port + "]");
notifyEvent("clientTaskId", Integer.valueOf(-1));
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
// Otherwise, the tunnel stays up even though the port is down
// This doesn't work for CLI though... and the tunnel doesn't close itself after error,
// so this probably leaves the tunnel open if called from the CLI
throw iae;
}
} else {
l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]");
@@ -686,6 +718,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {portNumber[, sharedClient][, proxy to be used for the WWW]}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runHttpClient(String args[], Logging l) {
if (args.length >= 1 && args.length <= 3) {
@@ -696,8 +729,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("httpclientTaskId", Integer.valueOf(-1));
return;
}
if (clientPort <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
String proxy = "";
boolean isShared = true;
@@ -732,6 +766,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
_log.error(getPrefix() + "Invalid I2PTunnel config to create an httpclient [" + host + ":"+ clientPort + "]", iae);
l.log("Invalid I2PTunnel configuration [" + host + ":" + clientPort + "]");
notifyEvent("httpclientTaskId", Integer.valueOf(-1));
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
// Otherwise, the tunnel stays up even though the port is down
// This doesn't work for CLI though... and the tunnel doesn't close itself after error,
// so this probably leaves the tunnel open if called from the CLI
throw iae;
}
} else {
l.log("httpclient <port> [<sharedClient>] [<proxy>]");
@@ -748,6 +787,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {portNumber[, sharedClient][, proxy to be used for the WWW]}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runConnectClient(String args[], Logging l) {
if (args.length >= 1 && args.length <= 3) {
@@ -756,8 +796,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
_port = Integer.parseInt(args[0]);
} catch (NumberFormatException nfe) {
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
return;
}
if (_port <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
String proxy = "";
boolean isShared = true;
@@ -788,7 +829,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
task = new I2PTunnelConnectClient(_port, l, ownDest, proxy, (EventDispatcher) this, this);
addtask(task);
} catch (IllegalArgumentException iae) {
_log.error(getPrefix() + "Invalid I2PTunnel config to create an httpclient [" + host + ":"+ _port + "]", iae);
_log.error(getPrefix() + "Invalid I2PTunnel config to create a connect client [" + host + ":"+ _port + "]", iae);
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
// Otherwise, the tunnel stays up even though the port is down
// This doesn't work for CLI though... and the tunnel doesn't close itself after error,
// so this probably leaves the tunnel open if called from the CLI
throw iae;
}
} else {
l.log("connectclient <port> [<sharedClient>] [<proxy>]");
@@ -808,6 +854,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {portNumber,destinationBase64 or "file:filename" [, sharedClient [, privKeyFile]]}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runIrcClient(String args[], Logging l) {
if (args.length >= 2) {
@@ -818,8 +865,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("ircclientTaskId", Integer.valueOf(-1));
return;
}
if (_port <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
boolean isShared = true;
if (args.length > 2) {
@@ -847,6 +895,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
_log.error(getPrefix() + "Invalid I2PTunnel config to create an ircclient [" + host + ":"+ _port + "]", iae);
l.log("Invalid I2PTunnel configuration [" + host + ":" + _port + "]");
notifyEvent("ircclientTaskId", Integer.valueOf(-1));
// Since nothing listens to TaskID events, use this to propagate the error to TunnelController
// Otherwise, the tunnel stays up even though the port is down
// This doesn't work for CLI though... and the tunnel doesn't close itself after error,
// so this probably leaves the tunnel open if called from the CLI
throw iae;
}
} else {
l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]");
@@ -866,6 +919,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {portNumber [, sharedClient]}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runSOCKSTunnel(String args[], Logging l) {
if (args.length >= 1 && args.length <= 2) {
@@ -876,8 +930,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
return;
}
if (_port <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
boolean isShared = false;
if (args.length > 1)
@@ -885,7 +940,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
ownDest = !isShared;
I2PTunnelTask task;
task = new I2PSOCKSTunnel(_port, l, ownDest, (EventDispatcher) this, this);
task = new I2PSOCKSTunnel(_port, l, ownDest, (EventDispatcher) this, this, null);
addtask(task);
notifyEvent("sockstunnelTaskId", Integer.valueOf(task.getId()));
} else {
@@ -895,11 +950,51 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
}
/**
* Run an SOCKS IRC tunnel on the given port number
* @param args {portNumber [, sharedClient]} or (portNumber, ignored (false), privKeyFile)
* @throws IllegalArgumentException on config problem
* @since 0.7.12
*/
public void runSOCKSIRCTunnel(String args[], Logging l) {
if (args.length >= 1 && args.length <= 3) {
int _port = -1;
try {
_port = Integer.parseInt(args[0]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
}
if (_port <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
boolean isShared = false;
if (args.length == 2)
isShared = "true".equalsIgnoreCase(args[1].trim());
ownDest = !isShared;
String privateKeyFile = null;
if (args.length == 3)
privateKeyFile = args[2];
I2PTunnelTask task;
task = new I2PSOCKSIRCTunnel(_port, l, ownDest, (EventDispatcher) this, this, privateKeyFile);
addtask(task);
notifyEvent("sockstunnelTaskId", Integer.valueOf(task.getId()));
} else {
l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]");
l.log(" creates a tunnel for SOCKS IRC.");
notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
}
}
/**
* Streamr client
*
* @param args {targethost, targetport, destinationString}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runStreamrClient(String args[], Logging l) {
if (args.length == 3) {
@@ -920,8 +1015,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1));
return;
}
if (_port <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
StreamrConsumer task = new StreamrConsumer(_host, _port, args[2], l, (EventDispatcher) this, this);
task.startRunning();
@@ -939,6 +1035,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
* @param args {port, privkeyfile}
* @param l logger to receive events and output
* @throws IllegalArgumentException on config problem
*/
public void runStreamrServer(String args[], Logging l) {
if (args.length == 2) {
@@ -949,8 +1046,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1));
return;
}
if (_port <= 0)
throw new IllegalArgumentException(getPrefix() + "Bad port " + args[0]);
File privKeyFile = new File(args[1]);
if (!privKeyFile.isAbsolute())
@@ -1365,6 +1463,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
/**
* Create a new destination, storing the destination and its private keys where
* instructed
* Deprecated - only used by CLI
*
* @param writeTo location to store the private keys
* @param pubDest location to store the destination
@@ -1389,6 +1488,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
/**
* Read in the given destination, display it, and write it to the given location
* Deprecated - only used by CLI
*
* @param readFrom stream to read the destination from
* @param pubDest stream to write the destination to
@@ -1410,6 +1510,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
/**
* Write out the destination to the stream
* Deprecated - only used by CLI
*
* @param d Destination to write
* @param o stream to write the destination to
@@ -1427,6 +1528,9 @@ public class I2PTunnel implements Logging, EventDispatcher {
* also supported, where filename is a file that either contains a
* binary Destination structure or the Base64 encoding of that
* structure.
*
* Since file:<filename> isn't really used, this method is deprecated,
* just call context.namingService.lookup() directly.
*/
public static Destination destFromName(String name) throws DataFormatException {
@@ -1491,7 +1595,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
}
private String getPrefix() { return '[' + _tunnelId + "]: "; }
private String getPrefix() { return "[" + _tunnelId + "]: "; }
public I2PAppContext getContext() { return _context; }

View File

@@ -8,7 +8,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
@@ -20,7 +19,7 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
private static final Log _log = new Log(I2PTunnelClient.class);
/** list of Destination objects that we point at */
protected List dests;
protected List<Destination> dests;
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
protected long readTimeout = DEFAULT_READ_TIMEOUT;
@@ -54,10 +53,21 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
}
}
if (dests.size() <= 0) {
l.log("No target destinations found");
if (dests.isEmpty()) {
l.log("No valid target destinations found");
notifyEvent("openClientResult", "error");
return;
// Nothing is listening for the above event, so it's useless
// Maybe figure out where to put a waitEventValue("openClientResult") ??
// In the meantime, let's do this the easy way
// Note that b32 dests will often not be resolvable at instantiation time;
// a delayed resolution system would be even better.
// Don't close() here, because it does a removeSession() and then
// TunnelController can't acquire() it to release() it.
//close(true);
// Unfortunately, super() built the whole tunnel before we get here.
throw new IllegalArgumentException("No valid target destinations found");
//return;
}
setName(getLocalPort() + " -> " + destinations);
@@ -78,8 +88,9 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
i2ps.setReadTimeout(readTimeout);
new I2PTunnelRunner(s, i2ps, sockLock, null, mySockets);
} catch (Exception ex) {
_log.info("Error connecting", ex);
l.log(ex.getMessage());
if (_log.shouldLog(Log.INFO))
_log.info("Error connecting", ex);
//l.log("Error connecting: " + ex.getMessage());
closeSocket(s);
if (i2ps != null) {
synchronized (sockLock) {
@@ -97,8 +108,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
return null;
}
if (size == 1) // skip the rand in the most common case
return (Destination)dests.get(0);
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
return (Destination)dests.get(index);
return dests.get(0);
int index = _context.random().nextInt(size);
return dests.get(index);
}
}

View File

@@ -583,6 +583,8 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
}
public boolean close(boolean forced) {
if (_log.shouldLog(Log.INFO))
_log.info("close() called: forced = " + forced + " open = " + open + " sockMgr = " + sockMgr);
if (!open) return true;
// FIXME: here we might have to wait quite a long time if
// there is a connection attempt atm. But without waiting we
@@ -641,7 +643,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
while (open) {
try {
synchronized (_waitingSockets) {
if (_waitingSockets.size() <= 0)
if (_waitingSockets.isEmpty())
_waitingSockets.wait();
else
s = (Socket)_waitingSockets.remove(0);

View File

@@ -26,6 +26,7 @@ import net.i2p.util.Log;
/**
* Supports the following:
*<pre>
* (where protocol is generally HTTP/1.1 but is ignored)
* (where host is one of:
* example.i2p
@@ -39,16 +40,19 @@ import net.i2p.util.Log;
* CONNECT host protocol
* CONNECT host:port
* CONNECT host:port protocol (this is the standard)
*</pre>
*
* Additional lines after the CONNECT line but before the blank line are ignored and stripped.
* The CONNECT line is removed for .i2p accesses
* but passed along for outproxy accesses.
*
* Ref:
*<pre>
* INTERNET-DRAFT Ari Luotonen
* Expires: September 26, 1997 Netscape Communications Corporation
* <draft-luotonen-ssl-tunneling-03.txt> March 26, 1997
* Tunneling SSL Through a WWW Proxy
*</pre>
*
* @author zzz a stripped-down I2PTunnelHTTPClient
*/
@@ -142,7 +146,7 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna
int size = _proxyList.size();
if (size <= 0)
return null;
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
int index = _context.random().nextInt(size);
return _proxyList.get(index);
}
}

View File

@@ -26,13 +26,13 @@ import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketOptions;
import net.i2p.data.Base32;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.util.EventDispatcher;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.Translate;
/**
@@ -46,8 +46,14 @@ import net.i2p.util.Translate;
* $method http://i2p/$b64key/$path $protocolVersion
* or
* $method /$site/$path $protocolVersion
* or (deprecated)
* $method /eepproxy/$site/$path $protocolVersion
* </pre>
*
* Note that http://i2p/$b64key/... and /eepproxy/$site/... are not recommended
* in browsers or other user-visible applications, as relative links will not
* resolve correctly, cookies won't work, etc.
*
* If the $site resolves with the I2P naming service, then it is directed towards
* that eepsite, otherwise it is directed towards this client's outproxy (typically
* "squid.i2p"). Only HTTP is supported (no HTTPS, ftp, mailto, etc). Both GET
@@ -196,10 +202,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (size <= 0) {
if (_log.shouldLog(Log.INFO))
_log.info("Proxy list is empty - no outproxy available");
l.log("Proxy list is emtpy - no outproxy available");
l.log("Proxy list is empty - no outproxy available");
return null;
}
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
int index = _context.random().nextInt(size);
String proxy = (String)proxyList.get(index);
return proxy;
}
@@ -303,14 +309,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (method == null) { // first line (GET /base64/realaddr)
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix(requestId) + "Method is null for [" + line + "]");
_log.debug(getPrefix(requestId) + "First line [" + line + "]");
int pos = line.indexOf(" ");
if (pos == -1) break;
method = line.substring(0, pos);
// TODO use Java URL class to make all this simpler and more robust
// That will also fix IPV6 [a:b:c]
String request = line.substring(pos + 1);
if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) {
// what is this for ???
request = "http://i2p" + request;
} else if (request.startsWith("/eepproxy/")) {
// /eepproxy/foo.i2p/bar/baz.html HTTP/1.0
@@ -322,6 +330,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
// "http://" + "foo.i2p/bar/baz.html" + " HTTP/1.0"
request = "http://" + uri + subRequest.substring(protopos);
} else if (request.toLowerCase().startsWith("http://i2p/")) {
// http://i2p/b64key/bar/baz.html HTTP/1.0
String subRequest = request.substring("http://i2p/".length());
int protopos = subRequest.indexOf(" ");
String uri = subRequest.substring(0, protopos);
if (uri.indexOf("/") == -1) {
uri = uri + "/";
}
// "http://" + "b64key/bar/baz.html" + " HTTP/1.0"
request = "http://" + uri + subRequest.substring(protopos);
}
pos = request.indexOf("//");
@@ -334,6 +352,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
targetRequest = request;
// pos is the start of the path
pos = request.indexOf("/");
if (pos == -1) {
method = null;
@@ -346,7 +365,17 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
int port = 80;
if(posPort != -1) {
String[] parts = host.split(":");
try {
host = parts[0];
} catch (ArrayIndexOutOfBoundsException ex) {
if (out != null) {
out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
writeFooter(out);
}
s.close();
return;
}
try {
port = Integer.parseInt(parts[1]);
} catch(Exception exc) {
@@ -354,9 +383,22 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
}
if (host.toLowerCase().equals("proxy.i2p")) {
// Go through the various types of host names, set
// the host and destination variables accordingly,
// and transform the first line.
// For all i2p network hosts, ensure that the host is a
// Base 32 hostname so that we do not reveal our name for it
// in our addressbook (all naming is local),
// and it is removed from the request line.
if (host.length() >= 516 && host.indexOf(".") < 0) {
// http://b64key/bar/baz.html
destination = host;
host = getHostName(destination);
line = method + ' ' + request.substring(pos);
} else if (host.toLowerCase().equals("proxy.i2p")) {
// so we don't do any naming service lookups
destination = "proxy.i2p";
destination = host;
usingInternalServer = true;
} else if (host.toLowerCase().endsWith(".i2p")) {
// Destination gets the host name
@@ -392,6 +434,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
// Key contains data, lets not ignore it
if (ahelperKey != null) {
// ahelperKey will be validated later
// Host resolvable only with addresshelper
if ( (host == null) || ("i2p".equals(host)) )
@@ -401,12 +444,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
} else {
// Host resolvable from database, verify addresshelper key
// Silently bypass correct keys, otherwise alert
if (!host.equals(ahelperKey))
String destB64 = null;
try {
Destination _dest = I2PTunnel.destFromName(host);
if (_dest != null)
destB64 = _dest.toBase64();
} catch (DataFormatException dfe) {}
if (destB64 != null && !destB64.equals(ahelperKey))
{
// Conflict: handle when URL reconstruction done
ahelperConflict = true;
if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix(requestId) + "Addresshelper key conflict for site [" + destination + "], trusted key [" + host + "], specified key [" + ahelperKey + "].");
_log.warn(getPrefix(requestId) + "Addresshelper key conflict for site [" + destination + "], trusted key [" + destB64 + "], specified key [" + ahelperKey + "].");
}
}
}
@@ -428,14 +477,22 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
{
if (out != null) {
long alias = I2PAppContext.getGlobalContext().random().nextLong();
String trustedURL = protocol + uriPath + urlEncoding;
String conflictURL = protocol + alias + ".i2p/?" + initialFragments;
byte[] header = getErrorPage("ahelper-conflict", ERR_AHELPER_CONFLICT);
out.write(header);
out.write(_("To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper link by temporarily giving it a random alias, click <a href=\"{1}\">here</a>.", trustedURL, conflictURL).getBytes("UTF-8"));
out.write(("<p></div>").getBytes());
writeFooter(out);
// convert ahelperKey to b32
String alias = getHostName(ahelperKey);
if (alias.equals("i2p")) {
// bad ahelperKey
byte[] header = getErrorPage("dnfb", ERR_DESTINATION_UNKNOWN);
writeErrorMessage(header, out, targetRequest, false, destination, null);
} else {
String trustedURL = protocol + uriPath + urlEncoding;
// Fixme - any path is lost
String conflictURL = protocol + alias + '/' + urlEncoding;
byte[] header = getErrorPage("ahelper-conflict", ERR_AHELPER_CONFLICT);
out.write(header);
out.write(_("To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, click <a href=\"{1}\">here</a>.", trustedURL, conflictURL).getBytes("UTF-8"));
out.write(("<p></div>").getBytes());
writeFooter(out);
}
}
s.close();
return;
@@ -450,7 +507,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
line = method + " " + request.substring(pos);
} else if (host.toLowerCase().equals("localhost") || host.equals("127.0.0.1")) {
} else if (host.toLowerCase().equals("localhost") || host.equals("127.0.0.1") ||
host.startsWith("192.168.")) {
// if somebody is trying to get to 192.168.example.com, oh well
if (out != null) {
out.write(getErrorPage("localhost", ERR_LOCALHOST));
writeFooter(out);
@@ -482,6 +541,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix(requestId) + "Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
} else {
// what is left for here? a hostname with no dots, and != "i2p"
// and not a destination ???
// Perhaps something in privatehosts.txt ...
request = request.substring(pos + 1);
pos = request.indexOf("/");
if (pos < 0) {
@@ -494,31 +556,49 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
return;
}
destination = request.substring(0, pos);
host = getHostName(destination);
line = method + " " + request.substring(pos);
} // end host name processing
if (port != 80 && !usingWWWProxy) {
if (out != null) {
out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
writeFooter(out);
}
s.close();
return;
}
boolean isValid = usingWWWProxy || usingInternalServer || isSupportedAddress(host, protocol);
if (!isValid) {
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")");
method = null;
destination = null;
break;
} else if ((!usingWWWProxy) && (!usingInternalServer)) {
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")");
host = getHostName(destination); // hide original host
}
// don't do this, it forces yet another hostname lookup,
// and in all cases host was already set above
//if ((!usingWWWProxy) && (!usingInternalServer)) {
// String oldhost = host;
// host = getHostName(destination); // hide original host
// if (_log.shouldLog(Log.INFO))
// _log.info(getPrefix(requestId) + " oldhost " + oldhost + " newhost " + host + " dest " + destination);
//}
if (_log.shouldLog(Log.DEBUG)) {
_log.debug(getPrefix(requestId) + "METHOD:" + method + ":");
_log.debug(getPrefix(requestId) + "PROTOC:" + protocol + ":");
_log.debug(getPrefix(requestId) + "HOST :" + host + ":");
_log.debug(getPrefix(requestId) + "DEST :" + destination + ":");
_log.debug(getPrefix(requestId) + "METHOD: \"" + method + "\"");
_log.debug(getPrefix(requestId) + "PROTOC: \"" + protocol + "\"");
_log.debug(getPrefix(requestId) + "HOST : \"" + host + "\"");
_log.debug(getPrefix(requestId) + "DEST : \"" + destination + "\"");
}
// end first line processing
} else {
if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) {
// Note that we only pass the original Host: line through to the outproxy
// But we don't create a Host: line if it wasn't sent to us
line = "Host: " + host;
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Setting host = " + host);
@@ -546,6 +626,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
//line = "From: i2p";
line = null;
continue; // completely strip the line
} else if (lowercaseLine.startsWith("authorization: ntlm ")) {
// Block Windows NTLM after 401
line = null;
continue;
} else if (lowercaseLine.startsWith("proxy-authorization: ntlm ")) {
// Block Windows NTLM after 407
line = null;
continue;
}
}
@@ -562,9 +650,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
newRequest.append("Accept-Encoding: \r\n");
newRequest.append("X-Accept-Encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0\r\n");
}
if (!Boolean.valueOf(getTunnel().getClientOptions().getProperty(PROP_USER_AGENT)).booleanValue())
newRequest.append("User-Agent: MYOB/6.66 (AN/ON)\r\n");
newRequest.append("Connection: close\r\n\r\n");
if (!Boolean.valueOf(getTunnel().getClientOptions().getProperty(PROP_USER_AGENT)).booleanValue()) {
// let's not advertise to external sites that we are from I2P
if (usingWWWProxy)
newRequest.append("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6\r\n");
else
newRequest.append("User-Agent: MYOB/6.66 (AN/ON)\r\n");
}
newRequest.append("Connection: close\r\n\r\n");
break;
} else {
newRequest.append(line).append("\r\n"); // HTTP spec
@@ -575,7 +668,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
_log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]");
if (method == null || destination == null) {
l.log("No HTTP method found in the request.");
//l.log("No HTTP method found in the request.");
if (out != null) {
if ("http://".equalsIgnoreCase(protocol))
out.write(getErrorPage("denied", ERR_REQUEST_DENIED));
@@ -598,7 +691,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
return;
}
Destination clientDest = I2PTunnel.destFromName(destination);
// If the host is "i2p", the getHostName() lookup failed, don't try to
// look it up again as the naming service does not do negative caching
// so it will be slow.
Destination clientDest;
if ("i2p".equals(host))
clientDest = null;
else
clientDest = I2PTunnel.destFromName(destination);
if (clientDest == null) {
//l.log("Could not resolve " + destination + ".");
if (_log.shouldLog(Log.WARN))
@@ -633,24 +735,27 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
Runnable onTimeout = new OnTimeout(s, s.getOutputStream(), targetRequest, usingWWWProxy, currentProxy, requestId);
I2PTunnelRunner runner = new I2PTunnelHTTPClientRunner(s, i2ps, sockLock, data, mySockets, onTimeout);
} catch (SocketException ex) {
_log.info(getPrefix(requestId) + "Error trying to connect", ex);
l.log(ex.getMessage());
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Error trying to connect", ex);
//l.log("Error connecting: " + ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
closeSocket(s);
} catch (IOException ex) {
_log.info(getPrefix(requestId) + "Error trying to connect", ex);
l.log(ex.getMessage());
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Error trying to connect", ex);
//l.log("Error connecting: " + ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
closeSocket(s);
} catch (I2PException ex) {
_log.info("getPrefix(requestId) + Error trying to connect", ex);
l.log(ex.getMessage());
if (_log.shouldLog(Log.INFO))
_log.info("getPrefix(requestId) + Error trying to connect", ex);
//l.log("Error connecting: " + ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
closeSocket(s);
} catch (OutOfMemoryError oom) {
IOException ex = new IOException("OOM");
_log.info("getPrefix(requestId) + Error trying to connect", ex);
l.log(ex.getMessage());
_log.error("getPrefix(requestId) + Error trying to connect", oom);
//l.log("Error connecting: " + ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
closeSocket(s);
}
@@ -662,6 +767,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
* We can't use BufferedReader for POST because we can't have readahead,
* since we are passing the stream on to I2PTunnelRunner for the POST data.
*
* Warning - BufferedReader removes \r, DataHelper does not
* Warning - DataHelper limits line length, BufferedReader does not
* Todo: Limit line length for buffered reads, or go back to unbuffered for all
*/
private static class InputReader {
BufferedReader _br;
@@ -671,20 +779,27 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
_s = s;
}
String readLine(String method) throws IOException {
if (method == null || "POST".equals(method))
// Use unbuffered until we can find a BufferedReader that limits line length
//if (method == null || "POST".equals(method))
return DataHelper.readLine(_s);
if (_br == null)
_br = new BufferedReader(new InputStreamReader(_s, "ISO-8859-1"));
return _br.readLine();
//if (_br == null)
// _br = new BufferedReader(new InputStreamReader(_s, "ISO-8859-1"));
//return _br.readLine();
}
}
/**
* @return b32hash.b32.i2p, or "i2p" on lookup failure.
* Prior to 0.7.12, returned b64 key
*/
private final static String getHostName(String host) {
if (host == null) return null;
if (host.length() == 60 && host.toLowerCase().endsWith(".b32.i2p"))
return host;
try {
Destination dest = I2PTunnel.destFromName(host);
if (dest == null) return "i2p";
return dest.toBase64();
return Base32.encode(dest.calculateHash().getData()) + ".b32.i2p";
} catch (DataFormatException dfe) {
return "i2p";
}
@@ -701,7 +816,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
* @return non-null
*/
private byte[] getErrorPage(String base, byte[] backup) {
return getErrorPage(getTunnel().getContext(), base, backup);
return getErrorPage(_context, base, backup);
}
private static byte[] getErrorPage(I2PAppContext ctx, String base, byte[] backup) {
@@ -858,8 +973,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
private final static String SUPPORTED_HOSTS[] = { "i2p", "www.i2p.com", "i2p."};
/** @param host ignored */
private static boolean isSupportedAddress(String host, String protocol) {
if ((host == null) || (protocol == null)) return false;
/****
* Let's not look up the name _again_
* and now that host is a b32, this was failing
*
boolean found = false;
String lcHost = host.toLowerCase();
for (int i = 0; i < SUPPORTED_HOSTS.length; i++) {
@@ -876,7 +997,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
} catch (DataFormatException dfe) {
}
}
****/
return protocol.equalsIgnoreCase("http://");
}

View File

@@ -151,7 +151,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
_log.warn("Took a while to handle the request [" + timeToHandle + ", socket create: " + (afterSocket-afterAccept) + "]");
}
private class CompressedRequestor implements Runnable {
private static class CompressedRequestor implements Runnable {
private Socket _webserver;
private I2PSocket _browser;
private String _headers;
@@ -214,7 +214,8 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
}
}
}
private class Sender implements Runnable {
private static class Sender implements Runnable {
private OutputStream _out;
private InputStream _in;
private String _name;
@@ -248,7 +249,8 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
}
}
}
private class CompressedResponseOutputStream extends HTTPResponseOutputStream {
private static class CompressedResponseOutputStream extends HTTPResponseOutputStream {
private InternalGZIPOutputStream _gzipOut;
public CompressedResponseOutputStream(OutputStream o) {
super(o);
@@ -287,7 +289,9 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
return 0;
}
}
private class InternalGZIPOutputStream extends GZIPOutputStream {
/** just a wrapper to provide stats for debugging */
private static class InternalGZIPOutputStream extends GZIPOutputStream {
public InternalGZIPOutputStream(OutputStream target) throws IOException {
super(target);
}
@@ -309,7 +313,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
}
}
private String formatHeaders(Properties headers, StringBuilder command) {
private static String formatHeaders(Properties headers, StringBuilder command) {
StringBuilder buf = new StringBuilder(command.length() + headers.size() * 64);
buf.append(command.toString().trim()).append("\r\n");
for (Iterator iter = headers.keySet().iterator(); iter.hasNext(); ) {
@@ -321,6 +325,9 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
return buf.toString();
}
/** ridiculously long, just to prevent OOM DOS @since 0.7.13 */
private static final int MAX_HEADERS = 60;
private Properties readHeaders(InputStream in, StringBuilder command) throws IOException {
Properties headers = new Properties();
StringBuilder buf = new StringBuilder(128);
@@ -344,7 +351,10 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
if (trimmed > 0)
getTunnel().getContext().statManager().addRateData("i2ptunnel.httpNullWorkaround", trimmed, 0);
int i = 0;
while (true) {
if (++i > MAX_HEADERS)
throw new IOException("Too many header lines - max " + MAX_HEADERS);
buf.setLength(0);
ok = DataHelper.readLine(in, buf);
if (!ok) throw new IOException("EOF reached before the end of the headers [" + buf.toString() + "]");

View File

@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
@@ -17,6 +16,9 @@ import net.i2p.util.EventDispatcher;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
/**
* Todo: Can we extend I2PTunnelClient instead and remove some duplicated code?
*/
public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable {
private static final Log _log = new Log(I2PTunnelIRCClient.class);
@@ -25,7 +27,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
private static volatile long __clientId = 0;
/** list of Destination objects that we point at */
protected List dests;
protected List<Destination> dests;
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
protected long readTimeout = DEFAULT_READ_TIMEOUT;
@@ -47,7 +49,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
"IRCHandler " + (++__clientId), tunnel, pkf);
StringTokenizer tok = new StringTokenizer(destinations, ", ");
dests = new ArrayList(1);
dests = new ArrayList(2);
while (tok.hasMoreTokens()) {
String destination = tok.nextToken();
try {
@@ -61,10 +63,21 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
}
}
if (dests.size() <= 0) {
if (dests.isEmpty()) {
l.log("No target destinations found");
notifyEvent("openClientResult", "error");
return;
// Nothing is listening for the above event, so it's useless
// Maybe figure out where to put a waitEventValue("openClientResult") ??
// In the meantime, let's do this the easy way
// Note that b32 dests will often not be resolvable at instantiation time;
// a delayed resolution system would be even better.
// Don't close() here, because it does a removeSession() and then
// TunnelController can't acquire() it to release() it.
//close(true);
// Unfortunately, super() built the whole tunnel before we get here.
throw new IllegalArgumentException("No valid target destinations found");
//return;
}
setName(getLocalPort() + " -> IRCClient");
@@ -82,15 +95,15 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
try {
i2ps = createI2PSocket(clientDest);
i2ps.setReadTimeout(readTimeout);
StringBuilder expectedPong = new StringBuilder();
Thread in = new I2PAppThread(new IrcInboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " in");
StringBuffer expectedPong = new StringBuffer();
Thread in = new I2PAppThread(new IrcInboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " in", true);
in.start();
Thread out = new I2PAppThread(new IrcOutboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " out");
Thread out = new I2PAppThread(new IrcOutboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " out", true);
out.start();
} catch (Exception ex) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error connecting", ex);
l.log(ex.getMessage());
//l.log("Error connecting: " + ex.getMessage());
closeSocket(s);
if (i2ps != null) {
synchronized (sockLock) {
@@ -109,27 +122,28 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
return null;
}
if (size == 1) // skip the rand in the most common case
return (Destination)dests.get(0);
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
return (Destination)dests.get(index);
return dests.get(0);
int index = _context.random().nextInt(size);
return dests.get(index);
}
/*************************************************************************
*
*/
private class IrcInboundFilter implements Runnable {
public static class IrcInboundFilter implements Runnable {
private Socket local;
private I2PSocket remote;
private StringBuilder expectedPong;
private StringBuffer expectedPong;
IrcInboundFilter(Socket _local, I2PSocket _remote, StringBuilder pong) {
public IrcInboundFilter(Socket _local, I2PSocket _remote, StringBuffer pong) {
local=_local;
remote=_remote;
expectedPong=pong;
}
public void run() {
// Todo: Don't use BufferedReader - IRC spec limits line length to 512 but...
BufferedReader in;
OutputStream output;
try {
@@ -167,6 +181,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
}
outmsg=outmsg+"\r\n"; // rfc1459 sec. 2.3
output.write(outmsg.getBytes("ISO-8859-1"));
// probably doesn't do much but can't hurt
output.flush();
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("inbound BLOCKED: "+inmsg);
@@ -191,19 +207,20 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
/*************************************************************************
*
*/
private class IrcOutboundFilter implements Runnable {
public static class IrcOutboundFilter implements Runnable {
private Socket local;
private I2PSocket remote;
private StringBuilder expectedPong;
private StringBuffer expectedPong;
IrcOutboundFilter(Socket _local, I2PSocket _remote, StringBuilder pong) {
public IrcOutboundFilter(Socket _local, I2PSocket _remote, StringBuffer pong) {
local=_local;
remote=_remote;
expectedPong=pong;
}
public void run() {
// Todo: Don't use BufferedReader - IRC spec limits line length to 512 but...
BufferedReader in;
OutputStream output;
try {
@@ -241,6 +258,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
}
outmsg=outmsg+"\r\n"; // rfc1459 sec. 2.3
output.write(outmsg.getBytes("ISO-8859-1"));
// save 250 ms in streaming
output.flush();
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("outbound BLOCKED: "+"\""+inmsg+"\"");
@@ -266,7 +285,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
*
*/
public String inboundFilter(String s, StringBuilder expectedPong) {
public static String inboundFilter(String s, StringBuffer expectedPong) {
String field[]=s.split(" ",4);
String command;
@@ -353,7 +372,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
return null;
}
public String outboundFilter(String s, StringBuilder expectedPong) {
public static String outboundFilter(String s, StringBuffer expectedPong) {
String field[]=s.split(" ",3);
String command;
@@ -371,14 +390,15 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
// "QUIT", // replace with a filtered QUIT to hide client quit messages
"SILENCE",
"MAP", // seems safe enough, the ircd should protect themselves though
"PART",
// "PART", // replace with filtered PART to hide client part messages
"OPER",
// "PONG", // replaced with a filtered PING/PONG since some clients send the server IP (thanks aardvax!)
// "PING",
"KICK",
"HELPME",
"RULES",
"TOPIC"
"TOPIC",
"ISON" // jIRCii uses this for a ping (response is 303)
};
if(field[0].length()==0)
@@ -390,7 +410,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
command = field[0].toUpperCase();
if ("PING".equalsIgnoreCase(command)) {
if ("PING".equals(command)) {
// Most clients just send a PING and are happy with any old PONG. Others,
// like BitchX, actually expect certain behavior. It sends two different pings:
// "PING :irc.freshcoffee.i2p" and "PING 1234567890 127.0.0.1" (where the IP is the proxy)
@@ -426,19 +446,19 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
return rv;
}
if ("PONG".equalsIgnoreCase(command))
if ("PONG".equals(command))
return "PONG 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
// Allow all allowedCommands
for(int i=0;i<allowedCommands.length;i++)
{
if(allowedCommands[i].equalsIgnoreCase(command))
if(allowedCommands[i].equals(command))
return s;
}
// mIRC sends "NOTICE user :DCC Send file (IP)"
// in addition to the CTCP version
if("NOTICE".equalsIgnoreCase(command))
if("NOTICE".equals(command))
{
String msg = field[2];
if(msg.startsWith(":DCC "))
@@ -447,7 +467,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
}
// Allow PRIVMSG, but block CTCP (except ACTION).
if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
if("PRIVMSG".equals(command) || "NOTICE".equals(command))
{
String msg;
msg = field[2];
@@ -465,14 +485,21 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
return s;
}
if("USER".equalsIgnoreCase(command)) {
if("USER".equals(command)) {
int idx = field[2].lastIndexOf(":");
if(idx<0)
return "USER user hostname localhost :realname";
String realname = field[2].substring(idx+1);
String ret = "USER "+field[1]+" hostname localhost :"+realname;
return ret;
} else if ("QUIT".equalsIgnoreCase(command)) {
}
if ("PART".equals(command)) {
// hide client message
return "PART " + field[1] + " :leaving";
}
if ("QUIT".equals(command)) {
return "QUIT :leaving";
}

View File

@@ -31,6 +31,9 @@ import net.i2p.util.Log;
*
* There are three options for mangling the desthash. Put the option in the
* "custom options" section of i2ptunnel.
* - ircserver.method unset: Defaults to user.
* - ircserver.method=user: Use method described above.
* - ircserver.method=webirc: Use the WEBIRC protocol.
* - ircserver.cloakKey unset: Cloak with a random value that is persistent for
* the life of this tunnel. This is the default.
* - ircserver.cloakKey=somepassphrase: Cloak with the hash of the passphrase. Use this to
@@ -39,6 +42,8 @@ import net.i2p.util.Log;
* be able to track users even when they switch servers.
* Note: don't quote or put spaces in the passphrase,
* the i2ptunnel gui can't handle it.
* - ircserver.webircPassword=password The password to use for the WEBIRC protocol.
* - ircserver.webircSpoofIP=IP The IP
* - ircserver.fakeHostname=%f.b32.i2p: Set the fake hostname sent by I2PTunnel,
* %f is the full B32 destination hash
* %c is the cloaked hash.
@@ -48,7 +53,12 @@ import net.i2p.util.Log;
* @author zzz
*/
public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
public static final String PROP_METHOD="ircserver.method";
public static final String PROP_METHOD_DEFAULT="user";
public static final String PROP_CLOAK="ircserver.cloakKey";
public static final String PROP_WEBIRC_PASSWORD="ircserver.webircPassword";
public static final String PROP_WEBIRC_SPOOF_IP="ircserver.webircSpoofIP";
public static final String PROP_WEBIRC_SPOOF_IP_DEFAULT="127.0.0.1";
public static final String PROP_HOSTNAME="ircserver.fakeHostname";
public static final String PROP_HOSTNAME_DEFAULT="%f.b32.i2p";
@@ -67,7 +77,20 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
/** generate a random 32 bytes, or the hash of the passphrase */
private void initCloak(I2PTunnel tunnel) {
// get the properties of this server-tunnel
Properties opts = tunnel.getClientOptions();
// get method of host faking
this.method = opts.getProperty(PROP_METHOD, PROP_METHOD_DEFAULT);
assert this.method != null;
// get the password for the webirc method
this.webircPassword = opts.getProperty(PROP_WEBIRC_PASSWORD);
// get the spoof IP for the webirc method
this.webircSpoofIP = opts.getProperty(PROP_WEBIRC_SPOOF_IP, PROP_WEBIRC_SPOOF_IP_DEFAULT);
// get the cloaking passphrase
String passphrase = opts.getProperty(PROP_CLOAK);
if (passphrase == null) {
this.cloakKey = new byte[Hash.HASH_LENGTH];
@@ -76,17 +99,30 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
this.cloakKey = SHA256Generator.getInstance().calculateHash(passphrase.trim().getBytes()).getData();
}
// get the fake hostmask to use
this.hostname = opts.getProperty(PROP_HOSTNAME, PROP_HOSTNAME_DEFAULT);
}
@Override
protected void blockingHandle(I2PSocket socket) {
try {
// give them 15 seconds to send in the request
socket.setReadTimeout(15*1000);
InputStream in = socket.getInputStream();
String modifiedRegistration = filterRegistration(in, cloakDest(socket.getPeerDestination()));
socket.setReadTimeout(readTimeout);
String modifiedRegistration;
if(!this.method.equals("webirc")) {
// give them 15 seconds to send in the request
socket.setReadTimeout(15*1000);
InputStream in = socket.getInputStream();
modifiedRegistration = filterRegistration(in, cloakDest(socket.getPeerDestination()));
socket.setReadTimeout(readTimeout);
} else {
StringBuffer buf = new StringBuffer("WEBIRC ");
buf.append(this.webircPassword);
buf.append(" cgiirc ");
buf.append(cloakDest(socket.getPeerDestination()));
buf.append(' ');
buf.append(this.webircSpoofIP);
buf.append("\r\n");
modifiedRegistration = buf.toString();
}
Socket s = new Socket(remoteHost, remotePort);
new I2PTunnelRunner(s, socket, slock, null, modifiedRegistration.getBytes(), null);
} catch (SocketException ex) {
@@ -134,7 +170,7 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
}
/** keep reading until we see USER or SERVER */
private String filterRegistration(InputStream in, String newHostname) throws IOException {
private static String filterRegistration(InputStream in, String newHostname) throws IOException {
StringBuilder buf = new StringBuilder(128);
int lineCount = 0;
@@ -185,4 +221,7 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
private byte[] cloakKey; // 32 bytes of stuff to scramble the dest with
private String hostname;
private String method;
private String webircPassword;
private String webircSpoofIP;
}

View File

@@ -124,11 +124,23 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr
OutputStream i2pout = i2ps.getOutputStream(); //new BufferedOutputStream(i2ps.getOutputStream(), MAX_PACKET_SIZE);
if (initialI2PData != null) {
synchronized (slock) {
// this does not increment totalSent
i2pout.write(initialI2PData);
i2pout.flush();
// do NOT flush here, it will block and then onTimeout.run() won't happen on fail.
// But if we don't flush, then we have to wait for the connectDelay timer to fire
// in i2p socket? To be researched and/or fixed.
//
// AS OF 0.8.1, MessageOutputStream.flush() is fixed to only wait for accept,
// not for "completion" (i.e. an ACK from the far end).
// So we now get a fast return from flush(), and can do it here to save 250 ms.
// To make sure we are under the initial window size and don't hang waiting for accept,
// only flush if it fits in one message.
if (initialI2PData.length <= 1730) // ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE
i2pout.flush();
}
}
if (initialSocketData != null) {
// this does not increment totalReceived
out.write(initialSocketData);
}
if (_log.shouldLog(Log.DEBUG))
@@ -150,6 +162,7 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr
if (_log.shouldLog(Log.DEBUG))
_log.debug("runner has a timeout job, totalReceived = " + totalReceived
+ " totalSent = " + totalSent + " job = " + onTimeout);
// should we only look at totalReceived?
if ( (totalSent <= 0) && (totalReceived <= 0) )
onTimeout.run();
}
@@ -271,7 +284,7 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr
//if (_log.shouldLog(Log.DEBUG))
// _log.debug("Flushing after sending " + len + " bytes through");
if (_log.shouldLog(Log.DEBUG))
_log.debug(direction + ": " + len + " bytes flushed through to "
_log.debug(direction + ": " + len + " bytes flushed through " + (_toI2P ? "to " : "from ")
+ i2ps.getPeerDestination().calculateHash().toBase64().substring(0,6));
try {
Thread.sleep(I2PTunnel.PACKET_DELAY);

View File

@@ -213,7 +213,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
sockMgr.getSession().destroySession();
} catch (I2PException ex) {
_log.error("Error destroying the session", ex);
System.exit(1);
//System.exit(1);
}
l.log("Server shut down.");
open = false;
@@ -294,6 +294,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
}
protected void blockingHandle(I2PSocket socket) {
if (_log.shouldLog(Log.INFO))
_log.info("Incoming connection to '" + toString() + "' from: " + socket.getPeerDestination().calculateHash().toBase64());
long afterAccept = I2PAppContext.getGlobalContext().clock().now();
long afterSocket = -1;
//local is fast, so synchronously. Does not need that many

View File

@@ -18,6 +18,7 @@ import net.i2p.data.Base32;
import net.i2p.data.Destination;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.SecureFileOutputStream;
/**
* Coordinate the runtime operation and configuration of a tunnel.
@@ -29,8 +30,8 @@ public class TunnelController implements Logging {
private Log _log;
private Properties _config;
private I2PTunnel _tunnel;
private List _messages;
private List _sessions;
private List<String> _messages;
private List<I2PSession> _sessions;
private boolean _running;
private boolean _starting;
@@ -46,6 +47,7 @@ public class TunnelController implements Logging {
public TunnelController(Properties config, String prefix) {
this(config, prefix, true);
}
/**
*
* @param createKey for servers, whether we want to create a brand new destination
@@ -58,17 +60,21 @@ public class TunnelController implements Logging {
setConfig(config, prefix);
_messages = new ArrayList(4);
_running = false;
boolean keyOK = true;
if (createKey && (getType().endsWith("server") || getPersistentClientKey()))
createPrivateKey();
_starting = getStartOnLoad();
keyOK = createPrivateKey();
_starting = keyOK && getStartOnLoad();
}
private void createPrivateKey() {
/**
* @return success
*/
private boolean createPrivateKey() {
I2PClient client = I2PClientFactory.createClient();
String filename = getPrivKeyFile();
if ( (filename == null) || (filename.trim().length() <= 0) ) {
log("No filename specified for the private key");
return;
return false;
}
File keyFile = new File(getPrivKeyFile());
@@ -76,7 +82,7 @@ public class TunnelController implements Logging {
keyFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), getPrivKeyFile());
if (keyFile.exists()) {
//log("Not overwriting existing private keys in " + keyFile.getAbsolutePath());
return;
return true;
} else {
File parent = keyFile.getParentFile();
if ( (parent != null) && (!parent.exists()) )
@@ -84,7 +90,7 @@ public class TunnelController implements Logging {
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(keyFile);
fos = new SecureFileOutputStream(keyFile);
Destination dest = client.createDestination(fos);
String destStr = dest.toBase64();
log("Private key created and saved in " + keyFile.getAbsolutePath());
@@ -94,13 +100,16 @@ public class TunnelController implements Logging {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating new destination", ie);
log("Error creating new destination: " + ie.getMessage());
return false;
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating writing the destination to " + keyFile.getAbsolutePath(), ioe);
log("Error writing the keys to " + keyFile.getAbsolutePath());
return false;
} finally {
if (fos != null) try { fos.close(); } catch (IOException ioe) {}
}
return true;
}
public void startTunnelBackground() {
@@ -120,9 +129,16 @@ public class TunnelController implements Logging {
} catch (Exception e) {
_log.error("Error starting up the tunnel", e);
log("Error starting up the tunnel - " + e.getMessage());
// if we don't acquire() then the release() in stopTunnel() won't work
acquire();
stopTunnel();
}
_starting = false;
}
/**
* @throws IllegalArgumentException via methods in I2PTunnel
*/
private void doStartTunnel() {
if (_running) {
if (_log.shouldLog(Log.INFO))
@@ -144,6 +160,8 @@ public class TunnelController implements Logging {
startIrcClient();
} else if("sockstunnel".equals(type)) {
startSocksClient();
} else if("socksirctunnel".equals(type)) {
startSocksIRCClient();
} else if("connectclient".equals(type)) {
startConnectClient();
} else if ("client".equals(type)) {
@@ -211,6 +229,19 @@ public class TunnelController implements Logging {
_tunnel.runSOCKSTunnel(new String[] { listenPort, sharedClient }, this);
}
/** @since 0.7.12 */
private void startSocksIRCClient() {
setListenOn();
String listenPort = getListenPort();
String sharedClient = getSharedClient();
if (getPersistentClientKey()) {
String privKeyFile = getPrivKeyFile();
_tunnel.runSOCKSIRCTunnel(new String[] { listenPort, "false", privKeyFile }, this);
} else {
_tunnel.runSOCKSIRCTunnel(new String[] { listenPort, sharedClient }, this);
}
}
/*
* Streamr client is a UDP server, use the listenPort field for targetPort
* and the listenOnInterface field for the targetHost
@@ -241,15 +272,18 @@ public class TunnelController implements Logging {
* closed by some other tunnels
*/
private void acquire() {
List sessions = _tunnel.getSessions();
if (sessions != null) {
List<I2PSession> sessions = _tunnel.getSessions();
if (!sessions.isEmpty()) {
for (int i = 0; i < sessions.size(); i++) {
I2PSession session = (I2PSession)sessions.get(i);
I2PSession session = sessions.get(i);
if (_log.shouldLog(Log.INFO))
_log.info("Acquiring session " + session);
TunnelControllerGroup.getInstance().acquire(this, session);
}
_sessions = sessions;
} else {
_log.error("No sessions to acquire?");
if (_log.shouldLog(Log.WARN))
_log.warn("No sessions to acquire? for " + getName());
}
}
@@ -258,13 +292,16 @@ public class TunnelController implements Logging {
* no other tunnels are using them, close them.
*/
private void release() {
if (_sessions != null) {
if (_sessions != null && !_sessions.isEmpty()) {
for (int i = 0; i < _sessions.size(); i++) {
I2PSession s = (I2PSession)_sessions.get(i);
I2PSession s = _sessions.get(i);
if (_log.shouldLog(Log.INFO))
_log.info("Releasing session " + s);
TunnelControllerGroup.getInstance().release(this, s);
}
} else {
_log.error("No sessions to release?");
if (_log.shouldLog(Log.WARN))
_log.warn("No sessions to release? for " + getName());
}
}
@@ -355,7 +392,7 @@ public class TunnelController implements Logging {
_tunnel.port = "7654";
}
}
public void stopTunnel() {
_tunnel.runClose(new String[] { "forced", "all" }, this);
release();
@@ -417,14 +454,16 @@ public class TunnelController implements Logging {
public String getListenPort() { return _config.getProperty("listenPort"); }
public String getTargetDestination() { return _config.getProperty("targetDestination"); }
public String getProxyList() { return _config.getProperty("proxyList"); }
/** default true */
public String getSharedClient() { return _config.getProperty("sharedClient", "true"); }
/** default true */
public boolean getStartOnLoad() { return "true".equalsIgnoreCase(_config.getProperty("startOnLoad", "true")); }
public boolean getPersistentClientKey() { return Boolean.valueOf(_config.getProperty("option.persistentClientKey")).booleanValue(); }
public String getMyDestination() {
if (_tunnel != null) {
List sessions = _tunnel.getSessions();
List<I2PSession> sessions = _tunnel.getSessions();
for (int i = 0; i < sessions.size(); i++) {
I2PSession session = (I2PSession)sessions.get(i);
I2PSession session = sessions.get(i);
Destination dest = session.getMyDestination();
if (dest != null)
return dest.toBase64();
@@ -435,9 +474,9 @@ public class TunnelController implements Logging {
public String getMyDestHashBase32() {
if (_tunnel != null) {
List sessions = _tunnel.getSessions();
List<I2PSession> sessions = _tunnel.getSessions();
for (int i = 0; i < sessions.size(); i++) {
I2PSession session = (I2PSession)sessions.get(i);
I2PSession session = sessions.get(i);
Destination dest = session.getMyDestination();
if (dest != null)
return Base32.encode(dest.calculateHash().getData());
@@ -539,9 +578,9 @@ public class TunnelController implements Logging {
if ( (opts != null) && (opts.length() > 0) )
buf.append("Network options: ").append(opts).append("<br />\n");
if (_running) {
List sessions = _tunnel.getSessions();
List<I2PSession> sessions = _tunnel.getSessions();
for (int i = 0; i < sessions.size(); i++) {
I2PSession session = (I2PSession)sessions.get(i);
I2PSession session = sessions.get(i);
Destination dest = session.getMyDestination();
if (dest != null) {
buf.append("Destination hash: ").append(dest.calculateHash().toBase64()).append("<br />\n");
@@ -580,7 +619,7 @@ public class TunnelController implements Logging {
*
* @return list of messages pulled off (each is a String, earliest first)
*/
public List clearMessages() {
public List<String> clearMessages() {
List rv = null;
synchronized (this) {
rv = new ArrayList(_messages);

View File

@@ -20,18 +20,20 @@ import net.i2p.client.I2PSessionException;
import net.i2p.data.DataHelper;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.SecureFileOutputStream;
/**
* Coordinate a set of tunnels within the JVM, loading and storing their config
* to disk, and building new ones as requested.
*
* Warning - this is a singleton. Todo: fix
*/
public class TunnelControllerGroup {
private Log _log;
private final Log _log;
private static TunnelControllerGroup _instance;
static final String DEFAULT_CONFIG_FILE = "i2ptunnel.config";
private List _controllers;
private final List<TunnelController> _controllers;
private String _configFile = DEFAULT_CONFIG_FILE;
/**
@@ -40,7 +42,7 @@ public class TunnelControllerGroup {
* no more tunnels are using it)
*
*/
private final Map _sessions;
private final Map<I2PSession, Set<TunnelController>> _sessions;
public static TunnelControllerGroup getInstance() {
synchronized (TunnelControllerGroup.class) {
@@ -104,7 +106,7 @@ public class TunnelControllerGroup {
private class StartControllers implements Runnable {
public void run() {
for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = (TunnelController)_controllers.get(i);
TunnelController controller = _controllers.get(i);
if (controller.getStartOnLoad())
controller.startTunnel();
}
@@ -141,10 +143,10 @@ public class TunnelControllerGroup {
*
* @return list of messages from the controller as it is stopped
*/
public List removeController(TunnelController controller) {
public List<String> removeController(TunnelController controller) {
if (controller == null) return new ArrayList();
controller.stopTunnel();
List msgs = controller.clearMessages();
List<String> msgs = controller.clearMessages();
_controllers.remove(controller);
msgs.add("Tunnel " + controller.getName() + " removed");
return msgs;
@@ -155,10 +157,10 @@ public class TunnelControllerGroup {
*
* @return list of messages the tunnels generate when stopped
*/
public List stopAllControllers() {
List msgs = new ArrayList();
public List<String> stopAllControllers() {
List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = (TunnelController)_controllers.get(i);
TunnelController controller = _controllers.get(i);
controller.stopTunnel();
msgs.addAll(controller.clearMessages());
}
@@ -172,10 +174,10 @@ public class TunnelControllerGroup {
*
* @return list of messages the tunnels generate when started
*/
public List startAllControllers() {
List msgs = new ArrayList();
public List<String> startAllControllers() {
List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = (TunnelController)_controllers.get(i);
TunnelController controller = _controllers.get(i);
controller.startTunnelBackground();
msgs.addAll(controller.clearMessages());
}
@@ -190,10 +192,10 @@ public class TunnelControllerGroup {
*
* @return list of messages the tunnels generate when restarted
*/
public List restartAllControllers() {
List msgs = new ArrayList();
public List<String> restartAllControllers() {
List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = (TunnelController)_controllers.get(i);
TunnelController controller = _controllers.get(i);
controller.restartTunnel();
msgs.addAll(controller.clearMessages());
}
@@ -207,10 +209,10 @@ public class TunnelControllerGroup {
*
* @return list of messages the tunnels have generated
*/
public List clearAllMessages() {
List msgs = new ArrayList();
public List<String> clearAllMessages() {
List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = (TunnelController)_controllers.get(i);
TunnelController controller = _controllers.get(i);
msgs.addAll(controller.clearMessages());
}
return msgs;
@@ -240,7 +242,7 @@ public class TunnelControllerGroup {
TreeMap map = new TreeMap();
for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = (TunnelController)_controllers.get(i);
TunnelController controller = _controllers.get(i);
Properties cur = controller.getConfig("tunnel." + i + ".");
map.putAll(cur);
}
@@ -254,7 +256,7 @@ public class TunnelControllerGroup {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(cfgFile);
fos = new SecureFileOutputStream(cfgFile);
fos.write(buf.toString().getBytes("UTF-8"));
if (_log.shouldLog(Log.INFO))
_log.info("Config written to " + cfgFile.getPath());
@@ -296,7 +298,7 @@ public class TunnelControllerGroup {
*
* @return list of TunnelController objects
*/
public List getControllers() { return _controllers; }
public List<TunnelController> getControllers() { return _controllers; }
/**
@@ -306,7 +308,7 @@ public class TunnelControllerGroup {
*/
void acquire(TunnelController controller, I2PSession session) {
synchronized (_sessions) {
Set owners = (Set)_sessions.get(session);
Set<TunnelController> owners = _sessions.get(session);
if (owners == null) {
owners = new HashSet(1);
_sessions.put(session, owners);
@@ -326,10 +328,10 @@ public class TunnelControllerGroup {
void release(TunnelController controller, I2PSession session) {
boolean shouldClose = false;
synchronized (_sessions) {
Set owners = (Set)_sessions.get(session);
Set<TunnelController> owners = _sessions.get(session);
if (owners != null) {
owners.remove(controller);
if (owners.size() <= 0) {
if (owners.isEmpty()) {
if (_log.shouldLog(Log.INFO))
_log.info("After releasing session " + session + " by " + controller + ", no more owners remain");
shouldClose = true;

View File

@@ -0,0 +1,63 @@
/* I2PSOCKSTunnel is released under the terms of the GNU GPL,
* with an additional exception. For further details, see the
* licensing terms in I2PTunnel.java.
*
* Copyright (c) 2004 by human
*/
package net.i2p.i2ptunnel.socks;
import java.net.Socket;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.i2ptunnel.I2PTunnel;
import net.i2p.i2ptunnel.I2PTunnelIRCClient;
import net.i2p.i2ptunnel.Logging;
import net.i2p.util.EventDispatcher;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
/*
* Pipe SOCKS IRC connections through I2PTunnelIRCClient filtering,
* to get the best of both worlds:
*
* - SOCKS lets you specify the host so you don't have to set up
* a tunnel for each IRC server in advance
* - IRC filtering for security
*
* @since 0.7.12
* @author zzz
*/
public class I2PSOCKSIRCTunnel extends I2PSOCKSTunnel {
private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(I2PSOCKSIRCTunnel.class);
private static int __clientId = 0;
/** @param pkf private key file name or null for transient key */
public I2PSOCKSIRCTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel, String pkf) {
super(localPort, l, ownDest, notifyThis, tunnel, pkf);
setName(getLocalPort() + " -> SOCKSIRCTunnel");
}
/**
* Same as in I2PSOCKSTunnel, but run the filters from I2PTunnelIRCClient
* instead of I2PTunnelRunner
*/
@Override
protected void clientConnectionRun(Socket s) {
try {
//_log.error("SOCKS IRC Tunnel Start");
SOCKSServer serv = SOCKSServerFactory.createSOCKSServer(s);
Socket clientSock = serv.getClientSocket();
I2PSocket destSock = serv.getDestinationI2PSocket(this);
StringBuffer expectedPong = new StringBuffer();
Thread in = new I2PAppThread(new I2PTunnelIRCClient.IrcInboundFilter(clientSock, destSock, expectedPong), "SOCKS IRC Client " + (++__clientId) + " in", true);
in.start();
Thread out = new I2PAppThread(new I2PTunnelIRCClient.IrcOutboundFilter(clientSock, destSock, expectedPong), "SOCKS IRC Client " + __clientId + " out", true);
out.start();
} catch (SOCKSException e) {
_log.error("Error from SOCKS connection", e);
closeSocket(s);
}
}
}

View File

@@ -33,8 +33,9 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
// I2PSOCKSTunnel(localPort, l, ownDest, (EventDispatcher)null);
//}
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(localPort, ownDest, l, notifyThis, "SOCKSHandler", tunnel);
/** @param pkf private key file name or null for transient key */
public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest, EventDispatcher notifyThis, I2PTunnel tunnel, String pkf) {
super(localPort, ownDest, l, notifyThis, "SOCKSHandler", tunnel, pkf);
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openSOCKSTunnelResult", "error");

View File

@@ -224,7 +224,7 @@ public class SOCKS4aServer extends SOCKSServer {
throw new SOCKSException(err);
} else {
List<String> proxies = t.getProxies(connPort);
if (proxies == null || proxies.size() <= 0) {
if (proxies == null || proxies.isEmpty()) {
String err = "No outproxy configured for port " + connPort + " and no default configured either - host: " + connHostName;
_log.error(err);
try {

View File

@@ -89,10 +89,10 @@ public class SOCKS5Server extends SOCKSServer {
int method = Method.NO_ACCEPTABLE_METHODS;
for (int i = 0; i < nMethods; ++i) {
method = in.readByte() & 0xff;
if (method == Method.NO_AUTH_REQUIRED) {
int meth = in.readByte() & 0xff;
if (meth == Method.NO_AUTH_REQUIRED) {
// That's fine, we do support this method
break;
method = meth;
}
}
@@ -119,7 +119,7 @@ public class SOCKS5Server extends SOCKSServer {
int socksVer = in.readByte() & 0xff;
if (socksVer != SOCKS_VERSION_5) {
_log.debug("error in SOCKS5 request (protocol != 5? wtf?)");
throw new SOCKSException("Invalid protocol version in request");
throw new SOCKSException("Invalid protocol version in request: " + socksVer);
}
int command = in.readByte() & 0xff;
@@ -332,7 +332,7 @@ public class SOCKS5Server extends SOCKSServer {
throw new SOCKSException(err);
} else {
List<String> proxies = t.getProxies(connPort);
if (proxies == null || proxies.size() <= 0) {
if (proxies == null || proxies.isEmpty()) {
String err = "No outproxy configured for port " + connPort + " and no default configured either";
_log.error(err);
try {

View File

@@ -20,7 +20,7 @@ public class SOCKSServerFactory {
private final static Log _log = new Log(SOCKSServerFactory.class);
private final static String ERR_REQUEST_DENIED =
"HTTP/1.1 403 Access Denied\r\n" +
"HTTP/1.1 403 Access Denied - This is a SOCKS proxy, not a HTTP proxy\r\n" +
"Content-Type: text/html; charset=iso-8859-1\r\n" +
"Cache-control: no-cache\r\n" +
"\r\n" +

View File

@@ -50,7 +50,7 @@ public class SOCKSUDPUnwrapper implements Source, Sink {
int headerlen = h.getBytes().length;
byte unwrapped[] = new byte[data.length - headerlen];
System.arraycopy(unwrapped, 0, data, headerlen, unwrapped.length);
System.arraycopy(data, headerlen, unwrapped, 0, unwrapped.length);
this.sink.send(dest, unwrapped);
}

View File

@@ -39,8 +39,8 @@ public class SOCKSUDPWrapper implements Source, Sink {
byte[] header = h.getBytes();
byte wrapped[] = new byte[header.length + data.length];
System.arraycopy(wrapped, 0, header, 0, header.length);
System.arraycopy(wrapped, header.length, data, 0, data.length);
System.arraycopy(header, 0, wrapped, 0, header.length);
System.arraycopy(data, 0, wrapped, header.length, data.length);
this.sink.send(from, wrapped);
}

View File

@@ -13,11 +13,20 @@ import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import net.i2p.data.Base64;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.i2ptunnel.TunnelController;
import net.i2p.i2ptunnel.TunnelControllerGroup;
/**
* Ugly little accessor for the edit page
*
* Warning - This class is not part of the i2ptunnel API, and at some point
* it will be moved from the jar to the war.
* Usage by classes outside of i2ptunnel.war is deprecated.
*/
public class EditBean extends IndexBean {
public EditBean() { super(); }
@@ -64,6 +73,31 @@ public class EditBean extends IndexBean {
return "i2ptunnel" + tunnel + "-privKeys.dat";
}
public String getNameSignature(int tunnel) {
String spoof = getSpoofedHost(tunnel);
if (spoof.length() <= 0)
return "";
TunnelController tun = getController(tunnel);
if (tun == null)
return "";
String keyFile = tun.getPrivKeyFile();
if (keyFile != null && keyFile.trim().length() > 0) {
PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
try {
Destination d = pkf.getDestination();
if (d == null)
return "";
SigningPrivateKey privKey = pkf.getSigningPrivKey();
if (privKey == null)
return "";
//System.err.println("Signing " + spoof + " with " + Base64.encode(privKey.getData()));
Signature sig = _context.dsa().sign(spoof.getBytes("UTF-8"), privKey);
return Base64.encode(sig.getData());
} catch (Exception e) {}
}
return "";
}
public boolean startAutomatically(int tunnel) {
TunnelController tun = getController(tunnel);
if (tun != null)
@@ -85,7 +119,7 @@ public class EditBean extends IndexBean {
}
public boolean isInteractive(int tunnel) {
return getProperty(tunnel, "i2p.streaming.maxWindowSize", 128) == 12;
return getProperty(tunnel, "i2p.streaming.maxWindowSize", 128) == 16;
}
public int getTunnelDepth(int tunnel, int defaultLength) {
@@ -141,7 +175,7 @@ public class EditBean extends IndexBean {
}
public String getAccessList(int tunnel) {
return getProperty(tunnel, "i2cp.accessList", "").replaceAll(",", "\n");
return getProperty(tunnel, "i2cp.accessList", "").replace(",", "\n");
}
public boolean getClose(int tunnel) {

View File

@@ -9,6 +9,7 @@ package net.i2p.i2ptunnel.web;
*/
import java.util.concurrent.ConcurrentHashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -31,6 +32,9 @@ import net.i2p.util.Log;
/**
* Simple accessor for exposing tunnel info, but also an ugly form handler
*
* Warning - This class is not part of the i2ptunnel API, and at some point
* it will be moved from the jar to the war.
* Usage by classes outside of i2ptunnel.war is deprecated.
*/
public class IndexBean {
protected I2PAppContext _context;
@@ -38,10 +42,10 @@ public class IndexBean {
protected TunnelControllerGroup _group;
private String _action;
private int _tunnel;
private long _prevNonce;
private long _curNonce;
private long _nextNonce;
private String _passphrase;
//private long _prevNonce;
//private long _prevNonce2;
private String _curNonce;
//private long _nextNonce;
private String _type;
private String _name;
@@ -79,10 +83,17 @@ public class IndexBean {
public static final int NOT_RUNNING = 3;
public static final int STANDBY = 4;
public static final String PROP_TUNNEL_PASSPHRASE = "i2ptunnel.passphrase";
static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
/** deprecated unimplemented, now using routerconsole realm */
//public static final String PROP_TUNNEL_PASSPHRASE = "i2ptunnel.passphrase";
public static final String PROP_TUNNEL_PASSPHRASE = "consolePassword";
//static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
//static final String PROP_NONCE_OLD = PROP_NONCE + '2';
/** 3 wasn't enough for some browsers. They are reloading the page for some reason - maybe HEAD? @since 0.8.1 */
private static final int MAX_NONCES = 5;
/** store nonces in a static FIFO instead of in System Properties @since 0.8.1 */
private static final List<String> _nonces = new ArrayList(MAX_NONCES + 1);
static final String CLIENT_NICKNAME = "shared clients";
public static final String PROP_THEME_NAME = "routerconsole.theme";
public static final String DEFAULT_THEME = "light";
public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled";
@@ -92,33 +103,44 @@ public class IndexBean {
_context = I2PAppContext.getGlobalContext();
_log = _context.logManager().getLog(IndexBean.class);
_group = TunnelControllerGroup.getInstance();
_action = null;
_tunnel = -1;
_curNonce = -1;
_prevNonce = -1;
try {
String nonce = System.getProperty(PROP_NONCE);
if (nonce != null)
_prevNonce = Long.parseLong(nonce);
} catch (NumberFormatException nfe) {}
_nextNonce = _context.random().nextLong();
System.setProperty(PROP_NONCE, Long.toString(_nextNonce));
_curNonce = "-1";
addNonce();
_booleanOptions = new ConcurrentHashSet(4);
_otherOptions = new ConcurrentHashMap(4);
}
public long getNextNonce() { return _nextNonce; }
public void setNonce(String nonce) {
if ( (nonce == null) || (nonce.trim().length() <= 0) ) return;
try {
_curNonce = Long.parseLong(nonce);
} catch (NumberFormatException nfe) {
_curNonce = -1;
public static String getNextNonce() {
synchronized (_nonces) {
return _nonces.get(0);
}
}
public void setNonce(String nonce) {
if ( (nonce == null) || (nonce.trim().length() <= 0) ) return;
_curNonce = nonce;
}
/** add a random nonce to the head of the queue @since 0.8.1 */
private void addNonce() {
String nextNonce = Long.toString(_context.random().nextLong());
synchronized (_nonces) {
_nonces.add(0, nextNonce);
int sz = _nonces.size();
if (sz > MAX_NONCES)
_nonces.remove(sz - 1);
}
}
/** do we know this nonce? @since 0.8.1 */
private static boolean haveNonce(String nonce) {
synchronized (_nonces) {
return _nonces.contains(nonce);
}
}
/** deprecated unimplemented, now using routerconsole realm */
public void setPassphrase(String phrase) {
_passphrase = phrase;
}
public void setAction(String action) {
@@ -134,19 +156,16 @@ public class IndexBean {
}
}
private boolean validPassphrase(String proposed) {
if (proposed == null) return false;
/** just check if console password option is set, jetty will do auth */
private boolean validPassphrase() {
String pass = _context.getProperty(PROP_TUNNEL_PASSPHRASE);
if ( (pass != null) && (pass.trim().length() > 0) )
return pass.trim().equals(proposed.trim());
else
return false;
return pass != null && pass.trim().length() > 0;
}
private String processAction() {
if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
return "";
if ( (_prevNonce != _curNonce) && (!validPassphrase(_passphrase)) )
if ( (!haveNonce(_curNonce)) && (!validPassphrase()) )
return "Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.";
if ("Stop all".equals(_action))
return stopAll();
@@ -349,6 +368,7 @@ public class IndexBean {
return ( ("client".equals(type)) ||
("httpclient".equals(type)) ||
("sockstunnel".equals(type)) ||
("socksirctunnel".equals(type)) ||
("connectclient".equals(type)) ||
("streamrclient".equals(type)) ||
("ircclient".equals(type)));
@@ -385,6 +405,7 @@ public class IndexBean {
else if ("server".equals(internalType)) return _("Standard server");
else if ("httpserver".equals(internalType)) return _("HTTP server");
else if ("sockstunnel".equals(internalType)) return _("SOCKS 4/4a/5 proxy");
else if ("socksirctunnel".equals(internalType)) return _("SOCKS IRC proxy");
else if ("connectclient".equals(internalType)) return _("CONNECT/SSL/HTTPS proxy");
else if ("ircserver".equals(internalType)) return _("IRC server");
else if ("streamrclient".equals(internalType)) return _("Streamr client");
@@ -645,7 +666,7 @@ public class IndexBean {
}
public void setAccessList(String val) {
if (val != null)
_otherOptions.put("i2cp.accessList", val.trim().replaceAll("\r\n", ",").replaceAll("\n", ",").replaceAll(" ", ","));
_otherOptions.put("i2cp.accessList", val.trim().replace("\r\n", ",").replace("\n", ",").replace(" ", ","));
}
public void setCloseTime(String val) {
if (val != null) {

View File

@@ -159,27 +159,10 @@
%>
</label>
<input type="text" size="30" id="targetDestination" name="targetDestination" title="Destination of the Tunnel" value="<%=editBean.getClientDestination(curTunnel)%>" class="freetext" />
<span class="comment">(<%=intl._("name or destination")%>)</span>
<span class="comment">(<%=intl._("name or destination")%>; <%=intl._("b32 not recommended")%>)</span>
</div>
<% } %>
<% if (!"streamrclient".equals(tunnelType)) { %>
<div id="profileField" class="rowItem">
<label for="profile" accesskey="f">
<%=intl._("Profile")%>(<span class="accessKey">f</span>):
</label>
<select id="profile" name="profile" title="Connection Profile" class="selectbox">
<% boolean interactiveProfile = editBean.isInteractive(curTunnel);
%><option <%=(interactiveProfile == true ? "selected=\"selected\" " : "")%>value="interactive"><%=intl._("interactive connection")%> </option>
<option <%=(interactiveProfile == false ? "selected=\"selected\" " : "")%>value="bulk"><%=intl._("bulk connection (downloads/websites/BT)")%> </option>
</select>
</div>
<div id="delayConnectField" class="rowItem">
<label for="connectDelay" accesskey="y">
<%=intl._("Delay Connect")%>(<span class="accessKey">y</span>):
</label>
<input value="1000" type="checkbox" id="connectDelay" name="connectDelay" title="Delay Connection"<%=(editBean.shouldDelay(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" />
<span class="comment">(<%=intl._("for request/response connections")%>)</span>
</div>
<div id="sharedtField" class="rowItem">
<label for="shared" accesskey="h">
<%=intl._("Shared Client")%>(<span class="accessKey">h</span>):
@@ -277,7 +260,31 @@
<div class="subdivider">
<hr />
</div>
<% if (!"streamrclient".equals(tunnelType)) { %>
<div id="profileField" class="rowItem">
<label for="profile" accesskey="f">
<%=intl._("Profile")%>(<span class="accessKey">f</span>):
</label>
<select id="profile" name="profile" title="Connection Profile" class="selectbox">
<% boolean interactiveProfile = editBean.isInteractive(curTunnel);
%><option <%=(interactiveProfile == true ? "selected=\"selected\" " : "")%>value="interactive"><%=intl._("interactive connection")%> </option>
<option <%=(interactiveProfile == false ? "selected=\"selected\" " : "")%>value="bulk"><%=intl._("bulk connection (downloads/websites/BT)")%> </option>
</select>
</div>
<div id="delayConnectField" class="rowItem">
<label for="connectDelay" accesskey="y">
<%=intl._("Delay Connect")%>(<span class="accessKey">y</span>):
</label>
<input value="1000" type="checkbox" id="connectDelay" name="connectDelay" title="Delay Connection"<%=(editBean.shouldDelay(curTunnel) ? " checked=\"checked\"" : "")%> class="tickbox" />
<span class="comment">(<%=intl._("for request/response connections")%>)</span>
</div>
<div class="subdivider">
<hr />
</div>
<% } // !streamrclient %>
<div id="optionsField" class="rowItem">
<label><%=intl._("I2CP Options")%>:</label>
</div>
@@ -379,7 +386,7 @@
<hr />
</div>
<% if ("client".equals(tunnelType) || "ircclient".equals(tunnelType)) { %>
<% if ("client".equals(tunnelType) || "ircclient".equals(tunnelType) || "socksirctunnel".equals(tunnelType)) { %>
<div id="optionsField" class="rowItem">
<label for="privKeyFile" accesskey="k">
<%=intl._("Persistent private key")%>(<span class="accessKey">k</span>):
@@ -424,9 +431,9 @@
<span class="comment"><%=intl._("NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted.")%></span>
<div class="separator"><hr /></div>
<input type="hidden" value="true" name="removeConfirm" />
<button id="controlSave" accesskey="S" class="control" type="submit" name="action" value="Save changes" title="Save Changes"><%=intl._("Save")%>(<span class="accessKey">S</span>)</button>
<button id="controlDelete" <%=(editBean.allowJS() ? "onclick=\"if (!confirm('Are you sure you want to delete?')) { return false; }\" " : "")%>accesskey="D" class="control" type="submit" name="action" value="Delete this proxy" title="Delete this Proxy"><%=intl._("Delete")%>(<span class="accessKey">D</span>)</button>
<button id="controlCancel" class="control" type="submit" name="action" value="" title="Cancel"><%=intl._("Cancel")%></button>
<button id="controlDelete" <%=(editBean.allowJS() ? "onclick=\"if (!confirm('Are you sure you want to delete?')) { return false; }\" " : "")%>accesskey="D" class="control" type="submit" name="action" value="Delete this proxy" title="Delete this Proxy"><%=intl._("Delete")%>(<span class="accessKey">D</span>)</button>
<button id="controlSave" accesskey="S" class="control" type="submit" name="action" value="Save changes" title="Save Changes"><%=intl._("Save")%>(<span class="accessKey">S</span>)</button>
</div>
</div>
</div>

View File

@@ -187,18 +187,6 @@
<input type="text" size="30" id="privKeyFile" name="privKeyFile" title="Path to Private Key File" value="<%=editBean.getPrivateKeyFile(curTunnel)%>" class="freetext" />
</div>
<% if (!"streamrserver".equals(tunnelType)) { %>
<div id="profileField" class="rowItem">
<label for="profile" accesskey="f">
<%=intl._("Profile")%>(<span class="accessKey">f</span>):
</label>
<select id="profile" name="profile" title="Connection Profile" class="selectbox">
<% boolean interactiveProfile = editBean.isInteractive(curTunnel);
%><option <%=(interactiveProfile == true ? "selected=\"selected\" " : "")%>value="interactive"><%=intl._("interactive connection")%> </option>
<option <%=(interactiveProfile == false ? "selected=\"selected\" " : "")%>value="bulk"><%=intl._("bulk connection (downloads/websites/BT)")%> </option>
</select>
</div>
<% } // !streamrserver %>
<div id="destinationField" class="rowItem">
<label for="localDestination" accesskey="L">
<%=intl._("Local destination")%>(<span class="accessKey">L</span>):
@@ -208,7 +196,16 @@
<a href="/susidns/addressbook.jsp?book=private&hostname=<%=editBean.getTunnelName(curTunnel)%>&destination=<%=editBean.getDestinationBase64(curTunnel)%>#add"><%=intl._("Add to local addressbook")%></a>
<% } %>
</div>
<% if (("httpserver".equals(tunnelType)) || ("httpbidirserver".equals(tunnelType))) {
%><div id="sigField" class="rowItem">
<label for="signature">
<%=intl._("Hostname Signature")%>
</label>
<input type="text" size="30" readonly="readonly" title="Use to prove that the website name is for this destination" value="<%=editBean.getNameSignature(curTunnel)%>" wrap="off" class="freetext" />
</div>
<% } %>
<div class="footer">
</div>
</div>
@@ -290,6 +287,23 @@
<hr />
</div>
<% if (!"streamrserver".equals(tunnelType)) { %>
<div id="profileField" class="rowItem">
<label for="profile" accesskey="f">
<%=intl._("Profile")%>(<span class="accessKey">f</span>):
</label>
<select id="profile" name="profile" title="Connection Profile" class="selectbox">
<% boolean interactiveProfile = editBean.isInteractive(curTunnel);
%><option <%=(interactiveProfile == true ? "selected=\"selected\" " : "")%>value="interactive"><%=intl._("interactive connection")%> </option>
<option <%=(interactiveProfile == false ? "selected=\"selected\" " : "")%>value="bulk"><%=intl._("bulk connection (downloads/websites/BT)")%> </option>
</select>
</div>
<div class="subdivider">
<hr />
</div>
<% } // !streamrserver %>
<div id="optionsField" class="rowItem">
<label><%=intl._("I2CP Options")%>:</label>
</div>
@@ -341,7 +355,7 @@
<div id="optionsField" class="rowItem">
<label for="access" accesskey="s">
<%=intl._("Restricted Access List")%>(<span class="accessKey">s</span>): <i><%=intl._("Unimplemented")%></i>
<%=intl._("Restricted Access List")%>(<span class="accessKey">s</span>):
</label>
</div>
<div id="portField" class="rowItem">
@@ -457,9 +471,9 @@
<span class="comment"><%=intl._("NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted.")%></span>
<div class="separator"><hr /></div>
<input type="hidden" value="true" name="removeConfirm" />
<button id="controlSave" accesskey="S" class="control" type="submit" name="action" value="Save changes" title="Save Changes"><%=intl._("Save")%>(<span class="accessKey">S</span>)</button>
<button id="controlDelete" <%=(editBean.allowJS() ? "onclick=\"if (!confirm('Are you sure you want to delete?')) { return false; }\" " : "")%>accesskey="D" class="control" type="submit" name="action" value="Delete this proxy" title="Delete this Proxy"><%=intl._("Delete")%>(<span class="accessKey">D</span>)</button>
<button id="controlCancel" class="control" type="submit" name="action" value="" title="Cancel"><%=intl._("Cancel")%></button>
<button id="controlDelete" <%=(editBean.allowJS() ? "onclick=\"if (!confirm('Are you sure you want to delete?')) { return false; }\" " : "")%>accesskey="D" class="control" type="submit" name="action" value="Delete this proxy" title="Delete this Proxy"><%=intl._("Delete")%>(<span class="accessKey">D</span>)</button>
<button id="controlSave" accesskey="S" class="control" type="submit" name="action" value="Save changes" title="Save Changes"><%=intl._("Save")%>(<span class="accessKey">S</span>)</button>
</div>
</div>
</div>

View File

@@ -250,7 +250,8 @@
}
%></div>
<% if (!"sockstunnel".equals(indexBean.getInternalType(curClient))) { %>
<% if (!("sockstunnel".equals(indexBean.getInternalType(curClient)) ||
"socksirctunnel".equals(indexBean.getInternalType(curClient)))) { %>
<div class="destinationField rowItem">
<label>
<% if ("httpclient".equals(indexBean.getInternalType(curClient)) || "connectclient".equals(indexBean.getInternalType(curClient))) { %>
@@ -288,6 +289,7 @@
<option value="httpclient">HTTP</option>
<option value="ircclient">IRC</option>
<option value="sockstunnel">SOCKS 4/4a/5</option>
<option value="socksirctunnel">SOCKS IRC</option>
<option value="connectclient">CONNECT</option>
<option value="streamrclient">Streamr</option>
</select>

View File

@@ -1,30 +1,682 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2ptunnel package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
# foo <foo@bar>, 2009.
#
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2ptunnel package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
# foo <foo@bar>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: I2P i2ptunnel\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-12-10 00:50+0000\n"
"PO-Revision-Date: 2009-10-19 12:50+0000\n"
"Last-Translator: foo <foo@bar>\n"
"POT-Creation-Date: 2010-11-08 18:21+0000\n"
"PO-Revision-Date: 2010-11-13 03:16+0100\n"
"Last-Translator: mixxy <m1xxy@mail.i2p>\n"
"Language-Team: foo <foo@bar>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: German\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
#, java-format
msgid "To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, click <a href=\"{1}\">here</a>."
msgstr "Um das Ziel in Ihrer Host-Datenbank zu besuchen, klicken Sie <a href=\"{0}\">hier</a>, und um das Ziel aus der kollidierenden Adresshelfer-Anfrage zu besuchen, <a href=\"{1}\">hier</a>!"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:917
msgid "Click a link below to look for an address helper by using a \"jump\" service:"
msgstr "Durch Klicken auf einen der untenstehenden Links bekommen Sie einen Adresshelfer von einem \"Sprung\"-Service:"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:382
msgid "New Tunnel"
msgstr "Neuer Tunnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:402
msgid "Standard client"
msgstr "Standardklient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:403
msgid "HTTP client"
msgstr "HTTP-Klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:404
msgid "IRC client"
msgstr "IRC-Klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:405
msgid "Standard server"
msgstr "Standardserver"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:406
msgid "HTTP server"
msgstr "HTTP-Server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:407
msgid "SOCKS 4/4a/5 proxy"
msgstr "SOCKS-4/4a/5-Proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:408
msgid "SOCKS IRC proxy"
msgstr "SOCKS-IRC-Proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:409
msgid "CONNECT/SSL/HTTPS proxy"
msgstr "CONNECT/SSL/HTTPS-Proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:410
msgid "IRC server"
msgstr "IRC-Server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:411
msgid "Streamr client"
msgstr "Streamr-Klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:412
msgid "Streamr server"
msgstr "Streamr-Server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:413
msgid "HTTP bidir"
msgstr "HTTP Bidir"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:73
msgid "I2P Tunnel Manager - Edit Client Tunnel"
msgstr ""
msgstr "I2P-Tunnel-Manager - Kliententunnel bearbeiten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:93
msgid "Edit proxy settings"
msgstr "Proxyeinstellungen bearbeiten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:101
msgid "New proxy settings"
msgstr "Neue Proxyeinstellungen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:107
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:121
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:242
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:257
msgid "Name"
msgstr "Name"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:246
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:270
msgid "Type"
msgstr "Typ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:226
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
msgid "Description"
msgstr "Beschreibung"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:126
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:136
msgid "Target"
msgstr "Ziel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:130
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:132
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:167
msgid "Access Point"
msgstr "Zugriffspunkt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:137
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:179
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:207
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:157
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:172
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:228
msgid "required"
msgstr "benötigt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:150
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:142
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:183
msgid "Reachable by"
msgstr "Erreichbar von"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:162
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:195
msgid "Locally (127.0.0.1)"
msgstr "Lokal (127.0.0.1)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:166
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:199
msgid "Everyone (0.0.0.0)"
msgstr "Überall (0.0.0.0)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:170
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:203
msgid "LAN Hosts (Please specify your LAN address)"
msgstr "LAN-Hosts (Bitte geben Sie ihre LAN-Adressen an!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:186
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:205
msgid "Other"
msgstr "Anderen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:195
msgid "Outproxies"
msgstr "Ausgehende Proxies"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
msgid "Tunnel Destination"
msgstr "Ziel des Tunnels"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:214
msgid "name or destination"
msgstr "Name oder Ziel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:217
msgid "b32 not recommended"
msgstr "B32-Adressen nicht empfohlen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:223
msgid "Shared Client"
msgstr "versch. Klienten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:227
msgid "(Share tunnels with other clients and irc/httpclients? Change requires restart of client proxy)"
msgstr "(Soll dieser Tunnel mit anderen Klienten und IRC/HTTP-Klienten geteilt werden? Änderungen benötigen Neustart des Klientenproxys)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:231
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
msgid "Auto Start"
msgstr "Automatischer Start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:235
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
msgid "(Check the Box for 'YES')"
msgstr "(Aktiviere das Kästchen für 'ja')"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:237
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:258
msgid "Advanced networking options"
msgstr "Erweiterte Netzwerkoptionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:239
msgid "(NOTE: when this client proxy is configured to share tunnels, then these options are for all the shared proxy clients!)"
msgstr "(HINWEIS: Ist dieser Proxy konfiguriert, Tunnel mit anderen Klienten zu teilen, so gelten diese Optionen für alle Klienten des Proxys!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:260
msgid "Tunnel Options"
msgstr "Tunneloptionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:262
msgid "Length"
msgstr "Länge"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:250
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:269
msgid "0 hop tunnel (low anonymity, low latency)"
msgstr "0-Hop-Tunnel (geringe Anonymität, geringe Latenz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:254
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:273
msgid "1 hop tunnel (medium anonymity, medium latency)"
msgstr "1-Hop-Tunnel (mittlere Anonymität, mittlere Latenz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:258
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:277
msgid "2 hop tunnel (high anonymity, high latency)"
msgstr "2-Hop-Tunnel (hohe Anonymität, hohe Latenz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:262
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:281
msgid "3 hop tunnel (very high anonymity, poor performance)"
msgstr "3-Hop-Tunnel (sehr hohe Anonymität, geringe Leistung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:271
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:290
msgid "hop tunnel (very poor performance)"
msgstr "Hop-Tunnel (sehr geringe Leistung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:276
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:295
msgid "Variance"
msgstr "Varianz"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:283
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:302
msgid "0 hop variance (no randomisation, consistant performance)"
msgstr "0-Hop-Varianz (keine zufällige Längenveränderung, konsistente Leistung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:287
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:306
msgid "+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
msgstr "+ 0-1 Hop Varianz (mittlere zufällige Verlängerung, verringert die Leistung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:291
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:310
msgid "+ 0-2 hop variance (high additive randomisation, subtractive performance)"
msgstr "+ 0-2 Hops Varianz (hohe zufällige Verlängerung, verringerte Leistung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:295
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:314
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
msgstr "+/- 0-1 Hop Varianz (geringe zufällige Längenänderung, Standardleistung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:299
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:318
msgid "+/- 0-2 hop variance (not recommended)"
msgstr "+/- 0-2 Hops Varianz (nicht empfohlen)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:311
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:330
msgid "hop variance"
msgstr "Hops Varianz"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:316
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid "Count"
msgstr "Anzahl"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:323
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:342
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr "1 eingehender, 1 ausgehender Tunnel (geringe Bandbreitennutzung, weniger zuverlässig)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:327
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:346
msgid "2 inbound, 2 outbound tunnels (standard bandwidth usage, standard reliability)"
msgstr "2 eingehende, 2 ausgehende Tunnel (Standardbandbreitennutzung, zuverlässig)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:331
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:350
msgid "3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr "3 eingehende, 3 ausgehende Tunnel (hohe Bandbreitennutzung, zuverlässiger)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:340
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:359
msgid "tunnels"
msgstr "Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:345
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:364
msgid "Backup Count"
msgstr "Anzahl an Ersatztunneln"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:352
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:371
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr "0 Ersatztunnel (0 Redundanz, keine zusätzliche Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:356
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:375
msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
msgstr "1 Ersatztunnel in jede Richtung (geringe Redundanz, geringe Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:360
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:379
msgid "2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr "2 Ersatztunnel in jede Richtung (mittlere Redundanz, mittlere Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:364
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr "3 Ersatztunnel in jede Richtung (hohe Redundanz, hohe Ressourcennutzung)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:392
msgid "backup tunnels"
msgstr "Ersatztunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:380
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:399
msgid "Profile"
msgstr "Profil"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:387
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:406
msgid "interactive connection"
msgstr "Interaktive Verbindung"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:391
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:410
msgid "bulk connection (downloads/websites/BT)"
msgstr "Mengenverbindung (Download/Webseiten/BitTorrent)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:393
msgid "Delay Connect"
msgstr "Verbindung verzögern"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:397
msgid "for request/response connections"
msgstr "für Verbindungen mit Anfragen/Antworten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:414
msgid "I2CP Options"
msgstr "I2CP-Optionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:403
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:146
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:416
msgid "Host"
msgstr "Host"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:407
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:152
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:420
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:244
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:266
msgid "Port"
msgstr "Port"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:413
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:452
msgid "Reduce tunnel quantity when idle"
msgstr "Anzahl an Tunneln im Leerlauf reduzieren"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:415
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:429
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:437
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:449
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:459
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:426
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:442
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:454
msgid "Enable"
msgstr "aktiviert"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:419
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:458
msgid "Reduced tunnel count"
msgstr "Reduzierte Tunnelanzahl"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:423
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:443
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:462
msgid "Idle minutes"
msgstr "Minuten Inaktivität"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:427
msgid "Close tunnels when idle"
msgstr "nicht genutzte Tunnel schließen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:433
msgid "New Keys on Reopen"
msgstr "Neue Schlüssel beim Wiederöffnen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:441
msgid "Disable"
msgstr "deaktiviert"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:447
msgid "Delay tunnel open until required"
msgstr "Aufbau des Tunnela verzögern, bis dieser benötigt wird"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:457
msgid "Persistent private key"
msgstr "Dauerhafter privater Schlüssel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:463
msgid "File"
msgstr "Datei"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:467
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:235
msgid "Local destination"
msgstr "lokales Ziel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:471
msgid "(if known)"
msgstr "(falls bekannt)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:475
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:498
msgid "Custom options"
msgstr "Eigene Optionen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:479
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:502
msgid "NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted."
msgstr "HINWEIS: Falls der Tunnel gerade aktiv ist, werden die meisten Änderungen erst nach einem Neustart des Tunnels wirksam."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:481
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:504
msgid "Cancel"
msgstr "Abbrechen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:485
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:508
msgid "Delete"
msgstr "Löschen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:487
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:510
msgid "Save"
msgstr "Speichern"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:73
msgid "I2P Tunnel Manager - Edit Server Tunnel"
msgstr ""
msgstr "I2P-Tunnel-Manager - Servertunnel bearbeiten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:93
msgid "Edit server settings"
msgstr "Servereinstellungen ändern"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:101
msgid "New server settings"
msgstr "Neue Servereinstellungen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:214
msgid "Website name"
msgstr "Name der Webseite"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:218
msgid "(leave blank for outproxies)"
msgstr "(für ausgehende Proxies leer lassen)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:223
msgid "Private key file"
msgstr "private Schlüsseldatei"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
msgid "Add to local addressbook"
msgstr "zum lokalen Adressbuch hinzufügen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:252
msgid "Hostname Signature"
msgstr "Signatur des Namens"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:424
msgid "Encrypt Leaseset"
msgstr "Leaseset verschlüsseln"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:430
msgid "Encryption Key"
msgstr "Schlüssel zum verschlüsseln"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:434
msgid "Generate New Key"
msgstr "Erzeuge neuen Schlüssel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:436
msgid "Generate"
msgstr "Erzeugen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:438
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:496
msgid "(Tunnel must be stopped first)"
msgstr "(Tunnel muss zuerst beendet sein)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:440
msgid "Restricted Access List"
msgstr "Zugang beschränken"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:446
msgid "Access List"
msgstr "Zugangsliste"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:450
msgid "(Restrict to these clients only)"
msgstr "(Zugang wird auf diese Klienten beschränkt)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:466
msgid "New Certificate type"
msgstr "Neuer Zertifizierungstyp"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:468
msgid "None"
msgstr "Keiner"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:472
msgid "Hashcash (effort)"
msgstr "Hashcash (Durchsatz)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:478
msgid "Hashcash Calc Time"
msgstr "Hashcash Berechnungszeit"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:480
msgid "Estimate"
msgstr "Abschätzung"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:482
msgid "Hidden"
msgstr "Versteckt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:486
msgid "Signed (signed by)"
msgstr "Signiert (unterschrieben von)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:492
msgid "Modify Certificate"
msgstr "Zertifikat modifizieren"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:494
msgid "Modify"
msgstr "Modifizieren"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:71
msgid "I2P Tunnel Manager - List"
msgstr ""
msgstr "I2P-Tunnel-Manager - Liste"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:83
msgid "Status Messages"
msgstr "Statusnachrichten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:87
msgid "Refresh"
msgstr "Auffrischen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:91
msgid "Stop All"
msgstr "Alle stoppen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:95
msgid "Start All"
msgstr "Alle starten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:99
msgid "Restart All"
msgstr "Alle neustarten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:103
msgid "Reload Config"
msgstr "Konfiguration neu einlesen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:105
msgid "I2P Server Tunnels"
msgstr "I2P-Servertunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:109
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:130
msgid "Points at"
msgstr "Läuft auf"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:111
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:153
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:157
msgid "Preview"
msgstr "Vorschau"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:113
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:177
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:250
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:278
msgid "Status"
msgstr "Status"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:163
msgid "Base32 Address"
msgstr "Basis-32-Adresse"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:171
msgid "No Preview"
msgstr "Keine Vorschau"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:184
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:285
msgid "Starting..."
msgstr "Starte ..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:191
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:205
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:292
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:306
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:320
msgid "Stop"
msgstr "Stopp"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:198
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:313
msgid "Running"
msgstr "Aktiv"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:212
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:327
msgid "Stopped"
msgstr "Gestoppt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:219
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:334
msgid "Start"
msgstr "Start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:234
msgid "New server tunnel"
msgstr "Neuer Servertunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:236
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
msgid "Standard"
msgstr "Standard"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:238
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
msgid "Create"
msgstr "Erstellen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:240
msgid "I2P Client Tunnels"
msgstr "I2P-Klienten-Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:248
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:274
msgid "Interface"
msgstr "Interface"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:299
msgid "Standby"
msgstr "Wartestellung"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:346
msgid "Outproxy"
msgstr "Ausgehender Proxy"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:350
msgid "Destination"
msgstr "Ziel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
msgid "New client tunnel"
msgstr "Neuer Kliententunnel"

View File

@@ -0,0 +1,689 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the i2ptunnel package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
# foo <foo@bar>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: I2P i2ptunnel\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-07-04 16:39+0000\n"
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
"Last-Translator: duck <duck@mail.i2p>\n"
"Language-Team: duck <duck@mail.i2p>, monkeybrains <monkeybrains@mail.i2p>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Dutch\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
#, java-format
msgid ""
"To visit the destination in your host database, click <a href=\"{0}\">here</"
"a>. To visit the conflicting addresshelper destination, click <a href=\"{1}"
"\">here</a>."
msgstr "Om de destination in je host database te bezoeken, klik <a href=\"{0}\">here</a>. Om de conflicterende adreshelper destination te bezoeken, klik <a href=\"{1}\">here</a>."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:909
msgid ""
"Click a link below to look for an address helper by using a \"jump\" service:"
msgstr "Klik op een onderstaande link om te zoeken naar een adreshelper via een \"jump\" service:"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:372
msgid "New Tunnel"
msgstr "Nieuwe Tunnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:392
msgid "Standard client"
msgstr "Standaard client"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:393
msgid "HTTP client"
msgstr "HTTP client"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:394
msgid "IRC client"
msgstr "IRC client"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:395
msgid "Standard server"
msgstr "Standaard server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:396
msgid "HTTP server"
msgstr "HTTP server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:397
msgid "SOCKS 4/4a/5 proxy"
msgstr "SOCKS 4/4a/5 proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:398
msgid "SOCKS IRC proxy"
msgstr "SOCKS IRC proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:399
msgid "CONNECT/SSL/HTTPS proxy"
msgstr "CONNECT/SSL/HTTPS proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:400
msgid "IRC server"
msgstr "IRC server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:401
msgid "Streamr client"
msgstr "Streamr client"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:402
msgid "Streamr server"
msgstr "Streamr server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:403
msgid "HTTP bidir"
msgstr "HTTP bidir"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:73
msgid "I2P Tunnel Manager - Edit Client Tunnel"
msgstr "I2P Tunnel Manager - Bewerk Client Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:93
msgid "Edit proxy settings"
msgstr "Bewerk proxy instellingen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:101
msgid "New proxy settings"
msgstr "Nieuwe proxy instellingen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:112
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:107
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:121
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:242
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:257
msgid "Name"
msgstr "Naam"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:116
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:246
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:270
msgid "Type"
msgstr "Type"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:226
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
msgid "Description"
msgstr "Omschrijving"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:126
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:136
msgid "Target"
msgstr "Doel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:130
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:132
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:167
msgid "Access Point"
msgstr "Toegangspunt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:137
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:179
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:207
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:157
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:172
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:228
msgid "required"
msgstr "vereist"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:150
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:142
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:183
msgid "Reachable by"
msgstr "Bereikbaar voor"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:162
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:195
msgid "Locally (127.0.0.1)"
msgstr "Lokaal (127.0.0.1)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:166
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:199
msgid "Everyone (0.0.0.0)"
msgstr "Iedereen (0.0.0.0)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:170
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:203
msgid "LAN Hosts (Please specify your LAN address)"
msgstr "LAN Hosts (Specificeer je LAN adres)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:186
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:205
msgid "Other"
msgstr "Anders"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:195
msgid "Outproxies"
msgstr "Uitgaande proxies"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:202
msgid "Tunnel Destination"
msgstr "Tunnel Destinations"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:214
msgid "name or destination"
msgstr "naam of destination"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:220
msgid "Shared Client"
msgstr "Gedeelde Client"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:224
msgid ""
"(Share tunnels with other clients and irc/httpclients? Change requires "
"restart of client proxy)"
msgstr "(Deel tunnels met andere clients en irc/httpclients? Wijziging vereist herstart van de client proxy)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:228
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
msgid "Auto Start"
msgstr "Auto Start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:232
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
msgid "(Check the Box for 'YES')"
msgstr "(Markeer de Box voor 'JA')"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:234
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:249
msgid "Advanced networking options"
msgstr "Geavanceerde netwerk opties"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:236
msgid ""
"(NOTE: when this client proxy is configured to share tunnels, then these "
"options are for all the shared proxy clients!)"
msgstr "(OPMERKING: wanneer deze client proxy is geconfigureerd om tunnels te delen, dan zijn deze opties van toepassing voor alle gedeelde proxy clients!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:238
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:251
msgid "Tunnel Options"
msgstr "Tunnel Opties"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:240
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:253
msgid "Length"
msgstr "Lengte"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:260
msgid "0 hop tunnel (low anonymity, low latency)"
msgstr "0 hop tunnel (lage anonimiteit, weinig vertraging)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:264
msgid "1 hop tunnel (medium anonymity, medium latency)"
msgstr "1 hop tunnel (gemiddelde anonimiteit, gemiddelde vertraging)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:255
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:268
msgid "2 hop tunnel (high anonymity, high latency)"
msgstr "2 hop tunnel (hoge anonimiteit, hoge vertraging)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:259
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:272
msgid "3 hop tunnel (very high anonymity, poor performance)"
msgstr "3 hop tunnel (zeer hoge anonimiteit, slechte prestatie)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:268
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:281
msgid "hop tunnel (very poor performance)"
msgstr "hop tunnel (zeer slechte prestatie)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:273
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:286
msgid "Variance"
msgstr "Variantie"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:280
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:293
msgid "0 hop variance (no randomisation, consistant performance)"
msgstr "0 hop variantie (geen randomisatie, consistente prestatie)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:284
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:297
msgid ""
"+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
msgstr "+ 0-1 hop variantie (gemiddeld toegevoegde randomisatie, minder prestatie)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:288
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:301
msgid ""
"+ 0-2 hop variance (high additive randomisation, subtractive performance)"
msgstr "+ 0-2 hop variantie (hoge toegevoegde randomisatie, minder prestatie)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:292
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:305
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
msgstr "+/- 0-1 hop variantie (standaard randomisatie, standaard prestatie)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:296
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:309
msgid "+/- 0-2 hop variance (not recommended)"
msgstr "+/- 0-2 hop variantie (niet aanbevolen)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:308
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:321
msgid "hop variance"
msgstr "hop variantie"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:313
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:326
msgid "Count"
msgstr "Aantal"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:320
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:333
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr "1 inkomende, 1 uitgaande tunnel (laag bandbreedte gebruik, minder betrouwbaar)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:324
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:337
msgid ""
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
"reliability)"
msgstr "2 inkomende, 2 uitgaande tunnels (standaard bandbreedte gebruik, standaard betrouwbaarheid)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:328
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:341
msgid ""
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr "3 inkomende, 3 uitgaande tunnels (hoge bandbreedte gebruik, hogere betrouwbaarheid)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:337
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:350
msgid "tunnels"
msgstr "tunnels"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:342
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:355
msgid "Backup Count"
msgstr "Backup Aantal"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:349
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:362
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr "0 backup tunnels (0 redundantie, geen additionele bronnen gebruikt)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:353
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:366
msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
msgstr "1 backup tunnel in beide richting (lage redundantie, lage aantal bronnen gebruikt)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:357
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:370
msgid ""
"2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr "2 backup tunnels in beide richting (gemiddelde redundantie, gemiddeld aantal bronnen gebruikt)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:361
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:374
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr "3 backup tunnels in beide richting (hoge redundantie, hoog aantal bronnen gebruikt)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:370
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
msgid "backup tunnels"
msgstr "backup tunnels"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:377
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:390
msgid "Profile"
msgstr "Profiel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:384
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:397
msgid "interactive connection"
msgstr "interactieve connectie"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:388
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:401
msgid "bulk connection (downloads/websites/BT)"
msgstr "bulk connection (downloads/websites/BT)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:390
msgid "Delay Connect"
msgstr "Vertraagde Connectie"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:394
msgid "for request/response connections"
msgstr "voor request/response connecties"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:398
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:405
msgid "I2CP Options"
msgstr "I2CP Opties"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:400
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:146
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:407
msgid "Host"
msgstr "Host"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:404
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:152
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:411
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:244
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:266
msgid "Port"
msgstr "Poort"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:410
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:443
msgid "Reduce tunnel quantity when idle"
msgstr "Verminder tunnel aantal wanneer in rust"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:412
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:426
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:434
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:446
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:456
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:417
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:433
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:445
msgid "Enable"
msgstr "Ingeschakeld"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:416
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:449
msgid "Reduced tunnel count"
msgstr "Verminder tunnel aantal"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:420
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:440
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:453
msgid "Idle minutes"
msgstr "Rust minuten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:424
msgid "Close tunnels when idle"
msgstr "Sluit tunnels wanneer in rust"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:430
msgid "New Keys on Reopen"
msgstr "Nieuwe Sleutels bij Heropenen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:438
msgid "Disable"
msgstr "Uitgeschakeld"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:444
msgid "Delay tunnel open until required"
msgstr "Vertraag tunnel opening totdat het nodig is"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:454
msgid "Persistent private key"
msgstr "Persistente private sleutel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:460
msgid "File"
msgstr "Bestand"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:464
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:235
msgid "Local destination"
msgstr "Lokale destination"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:468
msgid "(if known)"
msgstr "(indien bekend)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:472
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:489
msgid "Custom options"
msgstr "Aangepaste opties"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:476
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:493
msgid ""
"NOTE: If tunnel is currently running, most changes will not take effect "
"until tunnel is stopped and restarted."
msgstr "OPMERKING: Indien de tunnel op dit moment draait, zullen de meeste wijzigingen pas effect hebben na het stoppen en herstarten van de tunnel."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:478
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:495
msgid "Cancel"
msgstr "Annuleer"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:482
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:499
msgid "Delete"
msgstr "Verwijder"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:484
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:501
msgid "Save"
msgstr "Opslaan"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:73
msgid "I2P Tunnel Manager - Edit Server Tunnel"
msgstr "I2P Tunnel Manager - Bewerk Server Tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:93
msgid "Edit server settings"
msgstr "Bewerk server instellingen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:101
msgid "New server settings"
msgstr "Nieuwe server instellingen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:214
msgid "Website name"
msgstr "Website naam"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:218
msgid "(leave blank for outproxies)"
msgstr "(leeg laten voor uitgaande proxies)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:223
msgid "Private key file"
msgstr "Private sleutel bestand"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
msgid "Add to local addressbook"
msgstr "Toevoegen aan lokaal adresboek"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:415
msgid "Encrypt Leaseset"
msgstr "Versleutel Leaseset"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:421
msgid "Encryption Key"
msgstr "Encryptie Sleutel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:425
msgid "Generate New Key"
msgstr "Genereer Nieuwe Sleutel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:427
msgid "Generate"
msgstr "Genereer"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:429
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:487
msgid "(Tunnel must be stopped first)"
msgstr "(Tunnel moet eerst gestopt worden)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:431
msgid "Restricted Access List"
msgstr "Beperkte Toegangs Lijst"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:437
msgid "Access List"
msgstr "Toegangs Lijst"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:441
msgid "(Restrict to these clients only)"
msgstr "(Beperkt tot slechts deze clients)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:457
msgid "New Certificate type"
msgstr "Nieuw Certificaat type"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:459
msgid "None"
msgstr "Geen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:463
msgid "Hashcash (effort)"
msgstr "Hashcash (effort)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:469
msgid "Hashcash Calc Time"
msgstr "Hashcash Reken Tijd"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:471
msgid "Estimate"
msgstr "Inschatten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:473
msgid "Hidden"
msgstr "Verborgen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:477
msgid "Signed (signed by)"
msgstr "Ondertekend (ondertekend door)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:483
msgid "Modify Certificate"
msgstr "Wijzig Certificaat"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:485
msgid "Modify"
msgstr "Wijzig"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:71
msgid "I2P Tunnel Manager - List"
msgstr "I2P Tunnel Manager - Lijst"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:83
msgid "Status Messages"
msgstr "Status Berichten"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:87
msgid "Refresh"
msgstr "Ververs"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:91
msgid "Stop All"
msgstr "Stop Alles"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:95
msgid "Start All"
msgstr "Start Alles"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:99
msgid "Restart All"
msgstr "Herstart Alles"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:103
msgid "Reload Config"
msgstr "Herlaad Configuratie"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:105
msgid "I2P Server Tunnels"
msgstr "I2P Server Tunnels"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:109
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:130
msgid "Points at"
msgstr "Verwijst naar"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:111
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:153
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:157
msgid "Preview"
msgstr "Preview"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:113
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:177
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:250
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:278
msgid "Status"
msgstr "Status"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:163
msgid "Base32 Address"
msgstr "Base32 Adres"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:171
msgid "No Preview"
msgstr "Geen Preview"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:184
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:285
msgid "Starting..."
msgstr "Starten..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:191
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:205
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:292
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:306
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:320
msgid "Stop"
msgstr "Stop"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:198
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:313
msgid "Running"
msgstr "Draait"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:212
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:327
msgid "Stopped"
msgstr "Gestopt"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:219
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:334
msgid "Start"
msgstr "Start"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:234
msgid "New server tunnel"
msgstr "Nieuwe server tunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:236
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
msgid "Standard"
msgstr "Standaard"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:238
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
msgid "Create"
msgstr "Creëer"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:240
msgid "I2P Client Tunnels"
msgstr "I2P Client Tunnels"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:248
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:274
msgid "Interface"
msgstr "Interface"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:299
msgid "Standby"
msgstr "Stand-by"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:346
msgid "Outproxy"
msgstr "Uitgaande proxy"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:350
msgid "Destination"
msgstr "Destination"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
msgid "New client tunnel"
msgstr "Nieuwe client tunnel"

View File

@@ -8,69 +8,74 @@ msgid ""
msgstr ""
"Project-Id-Version: I2P i2ptunnel\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-01-14 06:24+0000\n"
"PO-Revision-Date: 2010-01-18 18:40+0000\n"
"Last-Translator: 4get <forget@mail.i2p>\n"
"POT-Creation-Date: 2010-11-13 22:04+0000\n"
"PO-Revision-Date: 2010-11-14 19:56+0500\n"
"Last-Translator: Hidden Z <hiddenz@mail.i2p>\n"
"Language-Team: foo <foo@bar>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: Russian\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:436
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:492
#, java-format
msgid "To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper link by temporarily giving it a random alias, click <a href=\"{1}\">here</a>."
msgstr "Для перехода по ссылке из локальной адресной книги, нажмите <a href=\"{0}\">здесь</a>. Для перехода по новой addresshelper-ссылке с временным присвоением ей случайного имени, нажмите <a href=\"{1}\">здесь</a>."
msgid "To visit the destination in your host database, click <a href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, click <a href=\"{1}\">here</a>."
msgstr "Для перехода по ссылке из локальной адресной книги, нажмите <a href=\"{0}\">здесь</a>. Для перехода по новой addresshelper-ссылке, нажмите <a href=\"{1}\">здесь</a>."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:802
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:917
msgid "Click a link below to look for an address helper by using a \"jump\" service:"
msgstr "Jump-сервисы, которые, возможно, знают нужную Вам addresshelper-ссылку:"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:362
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:382
msgid "New Tunnel"
msgstr "Новый туннель"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:382
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:402
msgid "Standard client"
msgstr "Обычный клиент"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:383
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:403
msgid "HTTP client"
msgstr "HTTP-клиент"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:384
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:404
msgid "IRC client"
msgstr "IRC-клиент"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:385
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:405
msgid "Standard server"
msgstr "Обычный сервер"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:386
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:406
msgid "HTTP server"
msgstr "HTTP-сервер"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:387
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:407
msgid "SOCKS 4/4a/5 proxy"
msgstr "SOCKS 4/4a/5 прокси"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:388
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:408
msgid "SOCKS IRC proxy"
msgstr "SOCKS IRC прокси"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:409
msgid "CONNECT/SSL/HTTPS proxy"
msgstr "CONNECT/SSL/HTTPS прокси"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:389
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:410
msgid "IRC server"
msgstr "IRC-сервер"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:390
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:411
msgid "Streamr client"
msgstr "Streamr-клиент"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:391
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:412
msgid "Streamr server"
msgstr "Streamr-сервер"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:392
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:413
msgid "HTTP bidir"
msgstr "HTTP bidir (экспериментальный двунаправленный режим, инструкцию спрашивайте у sponge)"
@@ -105,7 +110,7 @@ msgstr "Тип"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:120
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:226
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:357
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:358
msgid "Description"
msgstr "Описание"
@@ -167,284 +172,288 @@ msgstr "Адрес назначения туннеля"
msgid "name or destination"
msgstr "имя или адрес"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:220
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:237
msgid "Profile"
msgstr "Режим"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:217
msgid "b32 not recommended"
msgstr "b32 не рекомендуется"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:227
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:244
msgid "interactive connection"
msgstr "оптимизировать для малых задержек (irc)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:231
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:248
msgid "bulk connection (downloads/websites/BT)"
msgstr "оптимизировать для большого обьема (www/bittorrent)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:233
msgid "Delay Connect"
msgstr "Задержка соединения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:237
msgid "for request/response connections"
msgstr "оптимизация для соединений, начинающихся с запроса клиента/ответа сервера"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:239
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:223
msgid "Shared Client"
msgstr "Коллективный клиент"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:227
msgid "(Share tunnels with other clients and irc/httpclients? Change requires restart of client proxy)"
msgstr "(Использовать туннели коллективно/совместно с другими прокси-клиентами? Изменение настройки потребует перезапуска туннеля)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:247
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:231
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:124
msgid "Auto Start"
msgstr "Автозапуск"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:235
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:128
msgid "(Check the Box for 'YES')"
msgstr "(поставьте галочку для включения)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:266
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:237
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:258
msgid "Advanced networking options"
msgstr "Расширенные сетевые настройки"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:255
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:239
msgid "(NOTE: when this client proxy is configured to share tunnels, then these options are for all the shared proxy clients!)"
msgstr "(ПРИМЕЧАНИЕ: при коллективном использовании туннелей эти опции будут применяться ко всем коллективным прокси-клиентам!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:257
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:268
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:260
msgid "Tunnel Options"
msgstr "Параметры туннеля"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:259
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:270
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:243
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:262
msgid "Length"
msgstr "Длина"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:266
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:277
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:250
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:269
msgid "0 hop tunnel (low anonymity, low latency)"
msgstr "0 хопов (низкая анонимность, малые задержки)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:270
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:281
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:254
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:273
msgid "1 hop tunnel (medium anonymity, medium latency)"
msgstr "1 хоп (умеренная анонимность, умеренные задержки)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:274
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:285
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:258
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:277
msgid "2 hop tunnel (high anonymity, high latency)"
msgstr "2 хопа (высокая анонимность, высокие задержки)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:278
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:289
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:262
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:281
msgid "3 hop tunnel (very high anonymity, poor performance)"
msgstr "3 хопа (очень высокая анонимность, низкая производительность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:287
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:298
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:271
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:290
msgid "hop tunnel (very poor performance)"
msgstr "хопов (очень низкая производительность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:292
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:303
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:276
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:295
msgid "Variance"
msgstr "Разброс"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:299
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:310
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:283
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:302
msgid "0 hop variance (no randomisation, consistant performance)"
msgstr "нулевой разброс (без рандомизации, фиксированная производительность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:303
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:314
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:287
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:306
msgid "+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
msgstr "+ 0-1 разброс (умеренно повышенная рандомизация, пониженная производительность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:307
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:318
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:291
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:310
msgid "+ 0-2 hop variance (high additive randomisation, subtractive performance)"
msgstr "+ 0-2 разброс (сильно повышенная рандомизация, пониженная производительность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:311
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:322
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:295
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:314
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
msgstr "+/- 0-1 разброс (стандартная рандомизация, стандартная производительность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:315
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:326
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:299
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:318
msgid "+/- 0-2 hop variance (not recommended)"
msgstr "+/- 0-2 разброс (не рекомендуется)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:327
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:338
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:311
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:330
msgid "hop variance"
msgstr "разброс"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:332
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:343
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:316
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid "Count"
msgstr "Количество"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:339
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:350
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:323
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:342
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr "1 входящий, 1 исходящий туннель (низкая пропускная способность, низкая надежность) "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:343
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:354
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:327
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:346
msgid "2 inbound, 2 outbound tunnels (standard bandwidth usage, standard reliability)"
msgstr "2 входящих, 2 исходящих туннеля (стандартная пропускная способность, стандартная надежность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:347
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:358
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:331
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:350
msgid "3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr "3 входящих, 3 исходящих туннеля (высокая пропускная способность, высокая надежность)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:356
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:367
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:340
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:359
msgid "tunnels"
msgstr "туннелей"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:361
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:372
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:345
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:364
msgid "Backup Count"
msgstr "Резервное количество"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:368
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:379
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:352
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:371
msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr "без резервных туннелей (отсутствие избыточности, отсутствие дополнительной нагрузки на систему)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:372
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:356
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:375
msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
msgstr "1 резервный туннель в каждом направлении (низкая избыточность, низкая нагрузка на систему)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:376
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:387
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:360
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:379
msgid "2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr "2 резервных туннеля в каждом направлении (умеренная избыточность, умеренная нагрузка на систему)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:380
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:391
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:364
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr "3 резервных туннеля в каждом направлении (высокая избыточность, высокая нагрузка на систему)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:389
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:400
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:392
msgid "backup tunnels"
msgstr "резервных туннелей"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:394
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:405
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:380
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:399
msgid "Profile"
msgstr "Режим"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:387
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:406
msgid "interactive connection"
msgstr "оптимизировать для малых задержек (irc)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:391
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:410
msgid "bulk connection (downloads/websites/BT)"
msgstr "оптимизировать для большого обьема (www/bittorrent)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:393
msgid "Delay Connect"
msgstr "Задержка соединения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:397
msgid "for request/response connections"
msgstr "оптимизация для соединений, начинающихся с запроса клиента/ответа сервера"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:401
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:414
msgid "I2CP Options"
msgstr "Параметры I2CP"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:396
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:403
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:146
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:407
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:416
msgid "Host"
msgstr "Адрес"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:400
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:407
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:152
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:411
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:420
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:244
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:266
msgid "Port"
msgstr "Порт"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:406
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:445
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:413
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:452
msgid "Reduce tunnel quantity when idle"
msgstr "Снижать количество туннелей при простое"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:408
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:422
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:430
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:442
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:452
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:417
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:435
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:447
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:415
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:429
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:437
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:449
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:459
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:426
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:442
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:454
msgid "Enable"
msgstr "Включить"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:412
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:451
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:419
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:458
msgid "Reduced tunnel count"
msgstr "Количество туннелей"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:416
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:436
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:455
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:423
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:443
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:462
msgid "Idle minutes"
msgstr "Минут простоя"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:420
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:427
msgid "Close tunnels when idle"
msgstr "Закрыть туннели при простое"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:426
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:433
msgid "New Keys on Reopen"
msgstr "Генерировать новый ключ при переоткрытии"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:434
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:441
msgid "Disable"
msgstr "Выключить"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:440
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:447
msgid "Delay tunnel open until required"
msgstr "Отложить запуск до первого запроса"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:450
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:457
msgid "Persistent private key"
msgstr "Постоянный секретный ключ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:456
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:463
msgid "File"
msgstr "Файл"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:460
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:252
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:467
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:235
msgid "Local destination"
msgstr "Локальный адрес назначения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:464
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:471
msgid "(if known)"
msgstr "(если известен)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:468
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:491
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:475
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:498
msgid "Custom options"
msgstr "Дополнительные параметры"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:472
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:495
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:479
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:502
msgid "NOTE: If tunnel is currently running, most changes will not take effect until tunnel is stopped and restarted."
msgstr "ПРИМЕЧАНИЕ: для вступления в силу измененных настроек потребуется остановка и перезапуск туннеля"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:474
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:497
msgid "Save"
msgstr "Сохранить"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:481
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:504
msgid "Cancel"
msgstr "Отмена"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:478
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:501
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:485
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:508
msgid "Delete"
msgstr "Удалить"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:480
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:503
msgid "Cancel"
msgstr "Отмена"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:487
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:510
msgid "Save"
msgstr "Сохранить"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:73
msgid "I2P Tunnel Manager - Edit Server Tunnel"
@@ -470,80 +479,80 @@ msgstr "(не заполнять для outproxy)"
msgid "Private key file"
msgstr "Файл секретного ключа"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:262
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:245
msgid "Add to local addressbook"
msgstr "Добавить в локальную адресную книгу"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:415
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:252
msgid "Hostname Signature"
msgstr "Подпись хоста"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:424
msgid "Encrypt Leaseset"
msgstr "Шифровать LeaseSet"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:421
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:430
msgid "Encryption Key"
msgstr "Ключ шифрования"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:425
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:434
msgid "Generate New Key"
msgstr "Сгенерировать новый ключ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:427
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:436
msgid "Generate"
msgstr "Сгенерировать"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:429
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:489
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:438
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:496
msgid "(Tunnel must be stopped first)"
msgstr "(Туннель перед этим следует остановить)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:431
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:440
msgid "Restricted Access List"
msgstr "Ограниченный доступ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:433
msgid "Unimplemented"
msgstr "не реализовано"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:439
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:446
msgid "Access List"
msgstr "Список доступа"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:443
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:450
msgid "(Restrict to these clients only)"
msgstr "(Разрешить доступ только перечисленным клиентам)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:459
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:466
msgid "New Certificate type"
msgstr "Создать новый сертификат. Тип"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:461
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:468
msgid "None"
msgstr "Без"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:465
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:472
msgid "Hashcash (effort)"
msgstr "Hashcash (экспериментальный)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:471
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:478
msgid "Hashcash Calc Time"
msgstr "Время генерации hashcash-сертификата"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:473
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:480
msgid "Estimate"
msgstr "Прогноз"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:475
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:482
msgid "Hidden"
msgstr "Скрытый"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:479
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:486
msgid "Signed (signed by)"
msgstr "Подписанный (указать кем подписан)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:485
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:492
msgid "Modify Certificate"
msgstr "Изменить сертификат"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:487
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:494
msgid "Modify"
msgstr "Изменить"
@@ -638,12 +647,12 @@ msgid "New server tunnel"
msgstr "Новый серверный туннель"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:236
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:367
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368
msgid "Standard"
msgstr "Стандартный"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:238
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:369
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:370
msgid "Create"
msgstr "Создать"
@@ -661,15 +670,17 @@ msgid "Standby"
msgstr "Режим ожидания"
# This term intentionally left in English
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:345
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:346
msgid "Outproxy"
msgstr "Outproxy"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:349
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:350
msgid "Destination"
msgstr "Адрес назначения"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:365
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:366
msgid "New client tunnel"
msgstr "Новый клиентский туннель"
#~ msgid "Unimplemented"
#~ msgstr "не реализовано"

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,8 @@
<echo message="but strongly recommended, since they are used by some applications" />
<echo message="on top of I2P, like the router console." />
<echo message="" />
<echo message="Even if you deploy the Jetty archive manually, the build script will" />
<echo message="still attempt to verify its checksums, which must be:" />
<echo message="Even if you deploy the Jetty archive manually into directory apps/jetty/," />
<echo message="the build script will still attempt to verify its checksums, which must be:" />
<echo message="SHA1 ${jetty.sha1}" />
<echo message="" />
<input message="Download Jetty archive automatically?" validargs="y,n" addproperty="jetty.download" />

View File

@@ -1301,7 +1301,7 @@ public class HttpContext extends Container
List scss= _constraintMap.getMatches(pathInContext);
String pattern=null;
if (scss != null && scss.size() > 0)
if (scss != null && !scss.isEmpty())
{
Object constraints= null;

View File

@@ -0,0 +1,431 @@
// ========================================================================
// $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package org.mortbay.util;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.mortbay.log.LogFactory;
/* ------------------------------------------------------------ */
/** Abstract resource class.
*
* @version $Id: Resource.java,v 1.32 2009/05/16 01:53:36 gregwilkins Exp $
* @author Nuno Preguica
* @author Greg Wilkins (gregw)
*/
public abstract class Resource implements Serializable
{
private static Log log = LogFactory.getLog(Resource.class);
Object _associate;
/* ------------------------------------------------------------ */
/** Construct a resource from a url.
* @param url A URL.
* @return A Resource object.
*/
public static Resource newResource(URL url)
throws IOException
{
if (url==null)
return null;
String urls=url.toExternalForm();
if( urls.startsWith( "file:"))
{
try
{
FileResource fileResource= new FileResource(url);
return fileResource;
}
catch(Exception e)
{
log.debug(LogSupport.EXCEPTION,e);
return new BadResource(url,e.toString());
}
}
else if( urls.startsWith( "jar:file:"))
{
return new JarFileResource(url);
}
else if( urls.startsWith( "jar:"))
{
return new JarResource(url);
}
return new URLResource(url,null);
}
/* ------------------------------------------------------------ */
/** Construct a resource from a string.
* @param resource A URL or filename.
* @return A Resource object.
*/
public static Resource newResource(String resource)
throws MalformedURLException, IOException
{
URL url=null;
try
{
// Try to format as a URL?
url = new URL(resource);
}
catch(MalformedURLException e)
{
if(!resource.startsWith("ftp:") &&
!resource.startsWith("file:") &&
!resource.startsWith("jar:"))
{
try
{
// It's a file.
if (resource.startsWith("./"))
resource=resource.substring(2);
File file=new File(resource).getCanonicalFile();
url=file.toURI().toURL();
URLConnection connection=url.openConnection();
FileResource fileResource= new FileResource(url,connection,file);
return fileResource;
}
catch(Exception e2)
{
log.debug(LogSupport.EXCEPTION,e2);
throw e;
}
}
else
{
log.warn("Bad Resource: "+resource);
throw e;
}
}
String nurl=url.toString();
if (nurl.length()>0 &&
nurl.charAt(nurl.length()-1)!=
resource.charAt(resource.length()-1))
{
if ((nurl.charAt(nurl.length()-1)!='/' ||
nurl.charAt(nurl.length()-2)!=resource.charAt(resource.length()-1))
&&
(resource.charAt(resource.length()-1)!='/' ||
resource.charAt(resource.length()-2)!=nurl.charAt(nurl.length()-1)
))
{
return new BadResource(url,"Trailing special characters stripped by URL in "+resource);
}
}
return newResource(url);
}
/* ------------------------------------------------------------ */
/** Construct a system resource from a string.
* The resource is tried as classloader resource before being
* treated as a normal resource.
*/
public static Resource newSystemResource(String resource)
throws IOException
{
URL url=null;
// Try to format as a URL?
ClassLoader
loader=Thread.currentThread().getContextClassLoader();
if (loader!=null)
{
url=loader.getResource(resource);
if (url==null && resource.startsWith("/"))
url=loader.getResource(resource.substring(1));
}
if (url==null)
{
loader=Resource.class.getClassLoader();
if (loader!=null)
{
url=loader.getResource(resource);
if (url==null && resource.startsWith("/"))
url=loader.getResource(resource.substring(1));
}
}
if (url==null)
{
url=ClassLoader.getSystemResource(resource);
if (url==null && resource.startsWith("/"))
url=loader.getResource(resource.substring(1));
}
if (url==null)
return null;
return newResource(url);
}
/* ------------------------------------------------------------ */
protected void finalize()
{
release();
}
/* ------------------------------------------------------------ */
/** Release any resources held by the resource.
*/
public abstract void release();
/* ------------------------------------------------------------ */
/**
* Returns true if the respresened resource exists.
*/
public abstract boolean exists();
/* ------------------------------------------------------------ */
/**
* Returns true if the respresenetd resource is a container/directory.
* If the resource is not a file, resources ending with "/" are
* considered directories.
*/
public abstract boolean isDirectory();
/* ------------------------------------------------------------ */
/**
* Returns the last modified time
*/
public abstract long lastModified();
/* ------------------------------------------------------------ */
/**
* Return the length of the resource
*/
public abstract long length();
/* ------------------------------------------------------------ */
/**
* Returns an URL representing the given resource
*/
public abstract URL getURL();
/* ------------------------------------------------------------ */
/**
* Returns an File representing the given resource or NULL if this
* is not possible.
*/
public abstract File getFile()
throws IOException;
/* ------------------------------------------------------------ */
/**
* Returns the name of the resource
*/
public abstract String getName();
/* ------------------------------------------------------------ */
/**
* Returns an input stream to the resource
*/
public abstract InputStream getInputStream()
throws java.io.IOException;
/* ------------------------------------------------------------ */
/**
* Returns an output stream to the resource
*/
public abstract OutputStream getOutputStream()
throws java.io.IOException, SecurityException;
/* ------------------------------------------------------------ */
/**
* Deletes the given resource
*/
public abstract boolean delete()
throws SecurityException;
/* ------------------------------------------------------------ */
/**
* Rename the given resource
*/
public abstract boolean renameTo( Resource dest)
throws SecurityException;
/* ------------------------------------------------------------ */
/**
* Returns a list of resource names contained in the given resource
* The resource names are not URL encoded.
*/
public abstract String[] list();
/* ------------------------------------------------------------ */
/**
* Returns the resource contained inside the current resource with the
* given name.
* @param path The path segment to add, which should be encoded by the
* encode method.
*/
public abstract Resource addPath(String path)
throws IOException,MalformedURLException;
/* ------------------------------------------------------------ */
/** Encode according to this resource type.
* The default implementation calls URI.encodePath(uri)
* @param uri
* @return String encoded for this resource type.
*/
public String encode(String uri)
{
return URI.encodePath(uri);
}
/* ------------------------------------------------------------ */
public Object getAssociate()
{
return _associate;
}
/* ------------------------------------------------------------ */
public void setAssociate(Object o)
{
_associate=o;
}
/* ------------------------------------------------------------ */
/**
* @return The canonical Alias of this resource or null if none.
*/
public URL getAlias()
{
return null;
}
/* ------------------------------------------------------------ */
public CachedResource cache()
throws IOException
{
return new CachedResource(this);
}
/* ------------------------------------------------------------ */
/** Get the resource list as a HTML directory listing.
* @param base The base URL
* @param parent True if the parent directory should be included
* @return String of HTML
*/
public String getListHTML(String base,
boolean parent)
throws IOException
{
if (!isDirectory())
return null;
String[] ls = list();
if (ls==null)
return null;
Arrays.sort(ls);
String title = "Directory: "+URI.decodePath(base);
title=StringUtil.replace(StringUtil.replace(title,"<","&lt;"),">","&gt;");
StringBuffer buf=new StringBuffer(4096);
buf.append("<HTML><HEAD><TITLE>");
buf.append(title);
buf.append("</TITLE></HEAD><BODY>\n<H1>");
buf.append(title);
buf.append("</H1><TABLE BORDER=0>");
if (parent)
{
buf.append("<TR><TD><A HREF=");
buf.append(URI.encodePath(URI.addPaths(base,"../")));
buf.append(">Parent Directory</A></TD><TD></TD><TD></TD></TR>\n");
}
DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM);
for (int i=0 ; i< ls.length ; i++)
{
String encoded=URI.encodePath(ls[i]);
// bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
// http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
// See resource.diff attachment
//Resource item = addPath(encoded);
Resource item = addPath(ls[i]);
buf.append("<TR><TD><A HREF=\"");
String path=URI.addPaths(base,encoded);
if (item.isDirectory() && !path.endsWith("/"))
path=URI.addPaths(path,"/");
buf.append(path);
buf.append("\">");
buf.append(StringUtil.replace(StringUtil.replace(ls[i],"<","&lt;"),">","&gt;"));
buf.append("&nbsp;");
buf.append("</TD><TD ALIGN=right>");
buf.append(item.length());
buf.append(" bytes&nbsp;</TD><TD>");
buf.append(dfmt.format(new Date(item.lastModified())));
buf.append("</TD></TR>\n");
}
buf.append("</TABLE>\n");
buf.append("</BODY></HTML>\n");
return buf.toString();
}
/* ------------------------------------------------------------ */
/**
* @param out
* @param start First byte to write
* @param count Bytes to write or -1 for all of them.
*/
public void writeTo(OutputStream out,long start,long count)
throws IOException
{
InputStream in = getInputStream();
try
{
in.skip(start);
if (count<0)
IO.copy(in,out);
else
IO.copy(in,out,(int)count);
}
finally
{
in.close();
}
}
}

View File

@@ -69,7 +69,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
I2PSocket ret = null;
while ( (ret == null) && (!closing) ){
while (pendingSockets.size() <= 0) {
while (pendingSockets.isEmpty()) {
if (closing) throw new ConnectException("I2PServerSocket closed");
try {
synchronized(socketAddedLock) {
@@ -78,7 +78,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
} catch (InterruptedException ie) {}
}
synchronized (pendingSockets) {
if (pendingSockets.size() > 0) {
if (!pendingSockets.isEmpty()) {
ret = (I2PSocket)pendingSockets.remove(0);
}
}

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