forked from I2P_Developers/i2p.i2p
Compare commits
42 Commits
i2p_0_6_1_
...
i2p-0.6.1.
Author | SHA1 | Date | |
---|---|---|---|
ea0d4ffd7f | |||
1365d3e3b9 | |||
40befb5a92 | |||
9c16eec361 | |||
093c69637d | |||
134ec7acea | |||
0802a5ae40 | |||
14ddfb360f | |||
78ad831028 | |||
22f1684262 | |||
83f51b4a66 | |||
9c28de0704 | |||
c69fda2298 | |||
cabb22331b | |||
5b3aca29a8 | |||
f35cbf59d8 | |||
a96119d09b | |||
2711294aee | |||
f838b1828b | |||
fbf6282c1a | |||
5195a5c1fc | |||
62b18b18b5 | |||
7c8f519b35 | |||
d6fb979616 | |||
f568d21969 | |||
7fe9d590f5 | |||
0a1240ebfd | |||
4e68f2a157 | |||
e9bd6907d1 | |||
b20495c39f | |||
0ecbc4c27b | |||
4d5b1d4c3f | |||
17b719f3f7 | |||
979a3e98d8 | |||
c6a1112f0a | |||
4ebcc95d9f | |||
7e59ce27fa | |||
22345a264e | |||
03739996da | |||
819a72d4f6 | |||
e480931e20 | |||
3f01d0a69e |
@ -17,6 +17,10 @@
|
||||
# Contains the addresses from your master address book
|
||||
# and your subscribed address books. (../userhosts.txt)
|
||||
#
|
||||
# private_addressbook The path to the private address book used by the router.
|
||||
# This is used only by the router and SusiDNS.
|
||||
# It is not published by addressbook. (../privatehosts.txt)
|
||||
#
|
||||
# published_addressbook The path to the copy of your address book made
|
||||
# available on i2p. (../eepsite/docroot/hosts.txt)
|
||||
#
|
||||
@ -35,6 +39,7 @@ proxy_host=localhost
|
||||
proxy_port=4444
|
||||
master_addressbook=myhosts.txt
|
||||
router_addressbook=../userhosts.txt
|
||||
private_addressbook=../privatehosts.txt
|
||||
published_addressbook=../eepsite/docroot/hosts.txt
|
||||
log=log.txt
|
||||
subscriptions=subscriptions.txt
|
||||
|
@ -66,6 +66,7 @@ public class AddressBook {
|
||||
* where key is a human readable name, and value is a base64 i2p
|
||||
* destination.
|
||||
*/
|
||||
/* unused
|
||||
public AddressBook(String url, String proxyHost, int proxyPort) {
|
||||
this.location = url;
|
||||
EepGet get = new EepGet(I2PAppContext.getGlobalContext(), true,
|
||||
@ -79,23 +80,26 @@ public class AddressBook {
|
||||
}
|
||||
new File("addressbook.tmp").delete();
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Construct an AddressBook from the Subscription subscription. If the
|
||||
* address book at subscription has not changed since the last time it was
|
||||
* read or cannot be read, return an empty AddressBook.
|
||||
* Set a maximum size of the remote book to make it a little harder for a malicious book-sender.
|
||||
*
|
||||
* @param subscription
|
||||
* A Subscription instance pointing at a remote address book.
|
||||
*/
|
||||
static final long MAX_SUB_SIZE = 3 * 1024 * 1024l; //about 5,000 hosts
|
||||
public AddressBook(Subscription subscription, String proxyHost, int proxyPort) {
|
||||
this.location = subscription.getLocation();
|
||||
EepGet get = new EepGet(I2PAppContext.getGlobalContext(), true,
|
||||
proxyHost, proxyPort, 0, "addressbook.tmp",
|
||||
subscription.getLocation(), true, subscription.getEtag(), subscription.getLastModified());
|
||||
get.fetch();
|
||||
subscription.setEtag(get.getETag());
|
||||
subscription.setLastModified(get.getLastModified());
|
||||
proxyHost, proxyPort, 0, -1l, MAX_SUB_SIZE, "addressbook.tmp", null,
|
||||
subscription.getLocation(), true, subscription.getEtag(), subscription.getLastModified(), null);
|
||||
if (get.fetch()) {
|
||||
subscription.setEtag(get.getETag());
|
||||
subscription.setLastModified(get.getLastModified());
|
||||
}
|
||||
try {
|
||||
this.addresses = ConfigParser.parse(new File("addressbook.tmp"));
|
||||
} catch (IOException exp) {
|
||||
@ -152,6 +156,27 @@ public class AddressBook {
|
||||
return this.addresses.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do basic validation of the hostname and dest
|
||||
* hostname was already converted to lower case by ConfigParser.parse()
|
||||
*/
|
||||
private static boolean valid(String host, String dest) {
|
||||
return
|
||||
host.endsWith(".i2p") &&
|
||||
host.length() > 4 &&
|
||||
host.length() <= 67 && // 63 + ".i2p"
|
||||
(! host.startsWith(".")) &&
|
||||
(! host.startsWith("-")) &&
|
||||
(! host.endsWith("-.i2p")) &&
|
||||
host.indexOf("..") < 0 &&
|
||||
host.replaceAll("[a-z0-9.-]", "").length() == 0 &&
|
||||
|
||||
dest.length() == 516 &&
|
||||
dest.endsWith("AAAA") &&
|
||||
dest.replaceAll("[a-zA-Z0-9~-]", "").length() == 0
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge this AddressBook with AddressBook other, writing messages about new
|
||||
* addresses or conflicts to log. Addresses in AddressBook other that are
|
||||
@ -170,7 +195,7 @@ public class AddressBook {
|
||||
String otherKey = (String) otherIter.next();
|
||||
String otherValue = (String) other.addresses.get(otherKey);
|
||||
|
||||
if (otherKey.endsWith(".i2p") && otherValue.length() >= 516) {
|
||||
if (valid(otherKey, otherValue)) {
|
||||
if (this.addresses.containsKey(otherKey) && !overwrite) {
|
||||
if (!this.addresses.get(otherKey).equals(otherValue)
|
||||
&& log != null) {
|
||||
@ -185,7 +210,7 @@ public class AddressBook {
|
||||
this.modified = true;
|
||||
if (log != null) {
|
||||
log.append("New address " + otherKey
|
||||
+ " added to address book.");
|
||||
+ " added to address book. From: " + other.location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ public class ConfigParser {
|
||||
* a single key, value pair on each line, in the format: key=value. Lines
|
||||
* starting with '#' or ';' are considered comments, and ignored. Lines that
|
||||
* are obviously not in the format key=value are also ignored.
|
||||
* The key is converted to lower case.
|
||||
*
|
||||
* @param input
|
||||
* A BufferedReader with lines in key=value format to parse into
|
||||
@ -77,7 +78,7 @@ public class ConfigParser {
|
||||
inputLine = ConfigParser.stripComments(inputLine);
|
||||
String[] splitLine = inputLine.split("=");
|
||||
if (splitLine.length == 2) {
|
||||
result.put(splitLine[0].trim(), splitLine[1].trim());
|
||||
result.put(splitLine[0].trim().toLowerCase(), splitLine[1].trim());
|
||||
}
|
||||
inputLine = input.readLine();
|
||||
}
|
||||
@ -301,4 +302,4 @@ public class ConfigParser {
|
||||
new FileWriter(file, false)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,8 @@ public class Daemon {
|
||||
AddressBook router = new AddressBook(routerFile);
|
||||
|
||||
List defaultSubs = new LinkedList();
|
||||
defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt");
|
||||
// defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt");
|
||||
defaultSubs.add("http://www.i2p2.i2p/hosts.txt");
|
||||
|
||||
SubscriptionList subscriptions = new SubscriptionList(subscriptionFile,
|
||||
etagsFile, lastModifiedFile, defaultSubs, (String) settings
|
||||
|
@ -104,9 +104,9 @@ public class I2PSnarkUtil {
|
||||
if (opts.getProperty("outbound.nickname") == null)
|
||||
opts.setProperty("outbound.nickname", "I2PSnark");
|
||||
if (opts.getProperty("i2p.streaming.inactivityTimeout") == null)
|
||||
opts.setProperty("i2p.streaming.inactivityTimeout", "90000");
|
||||
opts.setProperty("i2p.streaming.inactivityTimeout", "240000");
|
||||
if (opts.getProperty("i2p.streaming.inactivityAction") == null)
|
||||
opts.setProperty("i2p.streaming.inactivityAction", "2"); // 1 == disconnect, 2 == ping
|
||||
opts.setProperty("i2p.streaming.inactivityAction", "1"); // 1 == disconnect, 2 == ping
|
||||
if (opts.getProperty("i2p.streaming.initialWindowSize") == null)
|
||||
opts.setProperty("i2p.streaming.initialWindowSize", "1");
|
||||
if (opts.getProperty("i2p.streaming.slowStartGrowthRateFactor") == null)
|
||||
|
@ -461,10 +461,12 @@ public class Peer implements Comparable
|
||||
public long getInactiveTime() {
|
||||
PeerState s = state;
|
||||
if (s != null) {
|
||||
PeerConnectionIn in = s.in;
|
||||
PeerConnectionOut out = s.out;
|
||||
if (out != null)
|
||||
return System.currentTimeMillis() - out.lastSent;
|
||||
else
|
||||
if (in != null && out != null) {
|
||||
long now = System.currentTimeMillis();
|
||||
return Math.max(now - out.lastSent, now - in.lastRcvd);
|
||||
} else
|
||||
return -1; //"state, no out";
|
||||
} else {
|
||||
return -1; //"no state";
|
||||
|
@ -35,10 +35,13 @@ class PeerConnectionIn implements Runnable
|
||||
private Thread thread;
|
||||
private volatile boolean quit;
|
||||
|
||||
long lastRcvd;
|
||||
|
||||
public PeerConnectionIn(Peer peer, DataInputStream din)
|
||||
{
|
||||
this.peer = peer;
|
||||
this.din = din;
|
||||
lastRcvd = System.currentTimeMillis();
|
||||
quit = false;
|
||||
}
|
||||
|
||||
@ -76,6 +79,7 @@ class PeerConnectionIn implements Runnable
|
||||
// Wait till we hear something...
|
||||
// The length of a complete message in bytes.
|
||||
int i = din.readInt();
|
||||
lastRcvd = System.currentTimeMillis();
|
||||
if (i < 0)
|
||||
throw new IOException("Unexpected length prefix: " + i);
|
||||
|
||||
|
@ -253,8 +253,8 @@ public class PeerCoordinator implements PeerListener
|
||||
synchronized(peers)
|
||||
{
|
||||
Peer old = peerIDInList(peer.getPeerID(), peers);
|
||||
if ( (old != null) && (old.getInactiveTime() > 4*60*1000) ) {
|
||||
// idle for 4 minutes, kill the old con (64KB/4min = 273B/sec minimum for one block)
|
||||
if ( (old != null) && (old.getInactiveTime() > 8*60*1000) ) {
|
||||
// idle for 8 minutes, kill the old con (32KB/8min = 68B/sec minimum for one block)
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Remomving old peer: " + peer + ": " + old + ", inactive for " + old.getInactiveTime());
|
||||
peers.remove(old);
|
||||
@ -315,7 +315,7 @@ public class PeerCoordinator implements PeerListener
|
||||
need_more = !peer.isConnected() && peers.size() < MAX_CONNECTIONS;
|
||||
// Check if we already have this peer before we build the connection
|
||||
Peer old = peerIDInList(peer.getPeerID(), peers);
|
||||
need_more = need_more && ((old == null) || (old.getInactiveTime() > 4*60*1000));
|
||||
need_more = need_more && ((old == null) || (old.getInactiveTime() > 8*60*1000));
|
||||
}
|
||||
|
||||
if (need_more)
|
||||
|
@ -598,7 +598,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
, "Gaytorrents", "http://uxPWHbK1OIj9HxquaXuhMiIvi21iK0~ZiG9d8G0840ZXIg0r6CbiV71xlsqmdnU6wm0T2LySriM0doW2gUigo-5BNkUquHwOjLROiETnB3ZR0Ml4IGa6QBPn1aAq2d9~g1r1nVjLE~pcFnXB~cNNS7kIhX1d6nLgYVZf0C2cZopEow2iWVUggGGnAA9mHjE86zLEnTvAyhbAMTqDQJhEuLa0ZYSORqzJDMkQt90MV4YMjX1ICY6RfUSFmxEqu0yWTrkHsTtRw48l~dz9wpIgc0a0T9C~eeWvmBFTqlJPtQZwntpNeH~jF7nlYzB58olgV2HHFYpVYD87DYNzTnmNWxCJ5AfDorm6AIUCV2qaE7tZtI1h6fbmGpGlPyW~Kw5GXrRfJwNvr6ajwAVi~bPVnrBwDZezHkfW4slOO8FACPR28EQvaTu9nwhAbqESxV2hCTq6vQSGjuxHeOuzBOEvRWkLKOHWTC09t2DbJ94FSqETmZopTB1ukEmaxRWbKSIaAAAA.i2p/announce.php=http://gaytorrents.i2p/"
|
||||
, "NickyB", "http://9On6d3cZ27JjwYCtyJJbowe054d5tFnfMjv4PHsYs-EQn4Y4mk2zRixatvuAyXz2MmRfXG-NAUfhKr0KCxRNZbvHmlckYfT-WBzwwpiMAl0wDFY~Pl8cqXuhfikSG5WrqdPfDNNIBuuznS0dqaczf~OyVaoEOpvuP3qV6wKqbSSLpjOwwAaQPHjlRtNIW8-EtUZp-I0LT45HSoowp~6b7zYmpIyoATvIP~sT0g0MTrczWhbVTUZnEkZeLhOR0Duw1-IRXI2KHPbA24wLO9LdpKKUXed05RTz0QklW5ROgR6TYv7aXFufX8kC0-DaKvQ5JKG~h8lcoHvm1RCzNqVE-2aiZnO2xH08H-iCWoLNJE-Td2kT-Tsc~3QdQcnEUcL5BF-VT~QYRld2--9r0gfGl-yDrJZrlrihHGr5J7ImahelNn9PpkVp6eIyABRmJHf2iicrk3CtjeG1j9OgTSwaNmEpUpn4aN7Kx0zNLdH7z6uTgCGD9Kmh1MFYrsoNlTp4AAAA.i2p/bittorrent/announce.php=http://nickyb.i2p/bittorrent/"
|
||||
, "Orion", "http://gKik1lMlRmuroXVGTZ~7v4Vez3L3ZSpddrGZBrxVriosCQf7iHu6CIk8t15BKsj~P0JJpxrofeuxtm7SCUAJEr0AIYSYw8XOmp35UfcRPQWyb1LsxUkMT4WqxAT3s1ClIICWlBu5An~q-Mm0VFlrYLIPBWlUFnfPR7jZ9uP5ZMSzTKSMYUWao3ejiykr~mtEmyls6g-ZbgKZawa9II4zjOy-hdxHgP-eXMDseFsrym4Gpxvy~3Fv9TuiSqhpgm~UeTo5YBfxn6~TahKtE~~sdCiSydqmKBhxAQ7uT9lda7xt96SS09OYMsIWxLeQUWhns-C~FjJPp1D~IuTrUpAFcVEGVL-BRMmdWbfOJEcWPZ~CBCQSO~VkuN1ebvIOr9JBerFMZSxZtFl8JwcrjCIBxeKPBmfh~xYh16BJm1BBBmN1fp2DKmZ2jBNkAmnUbjQOqWvUcehrykWk5lZbE7bjJMDFH48v3SXwRuDBiHZmSbsTY6zhGY~GkMQHNGxPMMSIAAAA.i2p/bt/announce.php=http://orion.i2p/bt/"
|
||||
, "anonymity", "http://8EoJZIKrWgGuDrxA3nRJs1jsPfiGwmFWL91hBrf0HA7oKhEvAna4Ocx47VLUR9retVEYBAyWFK-eZTPcvhnz9XffBEiJQQ~kFSCqb1fV6IfPiV3HySqi9U5Caf6~hC46fRd~vYnxmaBLICT3N160cxBETqH3v2rdxdJpvYt8q4nMk9LUeVXq7zqCTFLLG5ig1uKgNzBGe58iNcsvTEYlnbYcE930ABmrzj8G1qQSgSwJ6wx3tUQNl1z~4wSOUMan~raZQD60lRK70GISjoX0-D0Po9WmPveN3ES3g72TIET3zc3WPdK2~lgmKGIs8GgNLES1cXTolvbPhdZK1gxddRMbJl6Y6IPFyQ9o4-6Rt3Lp-RMRWZ2TG7j2OMcNSiOmATUhKEFBDfv-~SODDyopGBmfeLw16F4NnYednvn4qP10dyMHcUASU6Zag4mfc2-WivrOqeWhD16fVAh8MoDpIIT~0r9XmwdaVFyLcjbXObabJczxCAW3fodQUnvuSkwzAAAA.i2p/anonymityTracker/announce.php=http://anonymityweb.i2p/anonymityTracker/"
|
||||
// , "anonymity", "http://8EoJZIKrWgGuDrxA3nRJs1jsPfiGwmFWL91hBrf0HA7oKhEvAna4Ocx47VLUR9retVEYBAyWFK-eZTPcvhnz9XffBEiJQQ~kFSCqb1fV6IfPiV3HySqi9U5Caf6~hC46fRd~vYnxmaBLICT3N160cxBETqH3v2rdxdJpvYt8q4nMk9LUeVXq7zqCTFLLG5ig1uKgNzBGe58iNcsvTEYlnbYcE930ABmrzj8G1qQSgSwJ6wx3tUQNl1z~4wSOUMan~raZQD60lRK70GISjoX0-D0Po9WmPveN3ES3g72TIET3zc3WPdK2~lgmKGIs8GgNLES1cXTolvbPhdZK1gxddRMbJl6Y6IPFyQ9o4-6Rt3Lp-RMRWZ2TG7j2OMcNSiOmATUhKEFBDfv-~SODDyopGBmfeLw16F4NnYednvn4qP10dyMHcUASU6Zag4mfc2-WivrOqeWhD16fVAh8MoDpIIT~0r9XmwdaVFyLcjbXObabJczxCAW3fodQUnvuSkwzAAAA.i2p/anonymityTracker/announce.php=http://anonymityweb.i2p/anonymityTracker/"
|
||||
// , "The freak's tracker", "http://mHKva9x24E5Ygfey2llR1KyQHv5f8hhMpDMwJDg1U-hABpJ2NrQJd6azirdfaR0OKt4jDlmP2o4Qx0H598~AteyD~RJU~xcWYdcOE0dmJ2e9Y8-HY51ie0B1yD9FtIV72ZI-V3TzFDcs6nkdX9b81DwrAwwFzx0EfNvK1GLVWl59Ow85muoRTBA1q8SsZImxdyZ-TApTVlMYIQbdI4iQRwU9OmmtefrCe~ZOf4UBS9-KvNIqUL0XeBSqm0OU1jq-D10Ykg6KfqvuPnBYT1BYHFDQJXW5DdPKwcaQE4MtAdSGmj1epDoaEBUa9btQlFsM2l9Cyn1hzxqNWXELmx8dRlomQLlV4b586dRzW~fLlOPIGC13ntPXogvYvHVyEyptXkv890jC7DZNHyxZd5cyrKC36r9huKvhQAmNABT2Y~pOGwVrb~RpPwT0tBuPZ3lHYhBFYmD8y~AOhhNHKMLzea1rfwTvovBMByDdFps54gMN1mX4MbCGT4w70vIopS9yAAAA.i2p/bytemonsoon/announce.php"
|
||||
};
|
||||
|
||||
|
@ -131,6 +131,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
"Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>")
|
||||
.getBytes();
|
||||
|
||||
private final static int MAX_POSTBYTES = 20*1024*1024; // arbitrary but huge - all in memory, no temp file
|
||||
private final static byte[] ERR_MAXPOST =
|
||||
("HTTP/1.1 503 Bad POST\r\n"+
|
||||
"Content-Type: text/html; charset=iso-8859-1\r\n"+
|
||||
"Cache-control: no-cache\r\n"+
|
||||
"\r\n"+
|
||||
"<html><body><H1>I2P ERROR: REQUEST DENIED</H1>"+
|
||||
"The maximum POST size is " + MAX_POSTBYTES + " bytes.<BR>")
|
||||
.getBytes();
|
||||
|
||||
/** used to assign unique IDs to the threads / clients. no logic or functionality */
|
||||
private static volatile long __clientId = 0;
|
||||
|
||||
@ -503,12 +513,25 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]");
|
||||
|
||||
int postbytes = 0;
|
||||
while (br.ready()) { // empty the buffer (POST requests)
|
||||
int i = br.read();
|
||||
if (i != -1) {
|
||||
newRequest.append((char) i);
|
||||
if (++postbytes > MAX_POSTBYTES) {
|
||||
if (out != null) {
|
||||
out.write(ERR_MAXPOST);
|
||||
out.write("<p /><i>Generated on: ".getBytes());
|
||||
out.write(new Date().toString().getBytes());
|
||||
out.write("</i></body></html>\n".getBytes());
|
||||
out.flush();
|
||||
}
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (method == null || destination == null) {
|
||||
l.log("No HTTP method found in the request.");
|
||||
if (out != null) {
|
||||
@ -578,6 +601,12 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
l.log(ex.getMessage());
|
||||
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
|
||||
closeSocket(s);
|
||||
} catch (OutOfMemoryError oom) { // mainly for huge POSTs
|
||||
IOException ex = new IOException("OOM (in POST?)");
|
||||
_log.info("getPrefix(requestId) + Error trying to connect", ex);
|
||||
l.log(ex.getMessage());
|
||||
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
|
||||
closeSocket(s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -616,7 +645,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
private static String jumpServers[] = {"http://orion.i2p/jump/",
|
||||
private static String jumpServers[] = {
|
||||
"http://i2host.i2p/cgi-bin/i2hostjump?",
|
||||
"http://orion.i2p/jump/",
|
||||
"http://stats.i2p/cgi-bin/jump.cgi?a=",
|
||||
"http://trevorreznik.i2p/cgi-bin/jump.php?hostname="
|
||||
};
|
||||
private static void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
|
||||
|
@ -272,7 +272,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
int idx=0;
|
||||
final String[] allowedCommands =
|
||||
{
|
||||
"NOTICE",
|
||||
// "NOTICE", // can contain CTCP
|
||||
//"PING",
|
||||
//"PONG",
|
||||
"MODE",
|
||||
@ -306,34 +306,36 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
} catch(NumberFormatException nfe){}
|
||||
|
||||
|
||||
if ("PING".equals(command))
|
||||
if ("PING".equalsIgnoreCase(command))
|
||||
return "PING 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
|
||||
if ("PONG".equals(command)) {
|
||||
if ("PONG".equalsIgnoreCase(command)) {
|
||||
// Turn the received ":irc.freshcoffee.i2p PONG irc.freshcoffee.i2p :127.0.0.1"
|
||||
// into ":127.0.0.1 PONG 127.0.0.1 " so that the caller can append the client's extra parameter
|
||||
// though, does 127.0.0.1 work for irc clients connecting remotely? and for all of them? sure would
|
||||
// be great if irc clients actually followed the RFCs here, but i guess thats too much to ask.
|
||||
// If we haven't PINGed them, or the PING we sent isn't something we know how to filter, this
|
||||
// is blank.
|
||||
String pong = expectedPong.length() > 0 ? expectedPong.toString() : null;
|
||||
//
|
||||
// String pong = expectedPong.length() > 0 ? expectedPong.toString() : null;
|
||||
// If we aren't going to rewrite it, pass it through
|
||||
String pong = expectedPong.length() > 0 ? expectedPong.toString() : s;
|
||||
expectedPong.setLength(0);
|
||||
return pong;
|
||||
}
|
||||
|
||||
// Allow all allowedCommands
|
||||
for(int i=0;i<allowedCommands.length;i++) {
|
||||
if(allowedCommands[i].equals(command))
|
||||
if(allowedCommands[i].equalsIgnoreCase(command))
|
||||
return s;
|
||||
}
|
||||
|
||||
// Allow PRIVMSG, but block CTCP.
|
||||
if("PRIVMSG".equals(command))
|
||||
if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
|
||||
{
|
||||
String msg;
|
||||
msg = field[idx++];
|
||||
|
||||
byte[] bytes = msg.getBytes();
|
||||
if(bytes[1]==0x01)
|
||||
if(msg.indexOf(0x01) >= 0) // CTCP marker ^A can be anywhere, not just immediately after the ':'
|
||||
{
|
||||
// CTCP
|
||||
msg=msg.substring(2);
|
||||
@ -356,7 +358,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
String command;
|
||||
final String[] allowedCommands =
|
||||
{
|
||||
"NOTICE",
|
||||
// "NOTICE", // can contain CTCP
|
||||
"MODE",
|
||||
"JOIN",
|
||||
"NICK",
|
||||
@ -387,7 +389,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
|
||||
command = field[0].toUpperCase();
|
||||
|
||||
if ("PING".equals(command)) {
|
||||
if ("PING".equalsIgnoreCase(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)
|
||||
@ -403,13 +405,15 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
expectedPong.setLength(0);
|
||||
if (field.length == 1) { // PING
|
||||
rv = "PING";
|
||||
expectedPong.append("PONG 127.0.0.1");
|
||||
// If we aren't rewriting the PING don't rewrite the PONG
|
||||
// expectedPong.append("PONG 127.0.0.1");
|
||||
} else if (field.length == 2) { // PING nonce
|
||||
rv = "PING " + field[1];
|
||||
expectedPong.append("PONG ").append(field[1]);
|
||||
// If we aren't rewriting the PING don't rewrite the PONG
|
||||
// expectedPong.append("PONG ").append(field[1]);
|
||||
} else if (field.length == 3) { // PING nonce serverLocation
|
||||
rv = "PING " + field[1];
|
||||
expectedPong.append("PONG ").append(field[1]);
|
||||
expectedPong.append("PONG ").append(field[2]).append(" :").append(field[1]); // PONG serverLocation nonce
|
||||
} else {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("IRC client sent a PING we don't understand, filtering it (\"" + s + "\")");
|
||||
@ -417,28 +421,27 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("sending ping " + rv + ", waiting for " + expectedPong + " orig was [" + s + "]");
|
||||
_log.warn("sending ping [" + rv + "], waiting for [" + expectedPong + "] orig was [" + s + "]");
|
||||
|
||||
return rv;
|
||||
}
|
||||
if ("PONG".equals(command))
|
||||
if ("PONG".equalsIgnoreCase(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].equals(command))
|
||||
if(allowedCommands[i].equalsIgnoreCase(command))
|
||||
return s;
|
||||
}
|
||||
|
||||
// Allow PRIVMSG, but block CTCP (except ACTION).
|
||||
if("PRIVMSG".equals(command))
|
||||
if("PRIVMSG".equalsIgnoreCase(command) || "NOTICE".equalsIgnoreCase(command))
|
||||
{
|
||||
String msg;
|
||||
msg = field[2];
|
||||
|
||||
byte[] bytes = msg.getBytes();
|
||||
if(bytes[1]==0x01)
|
||||
if(msg.indexOf(0x01) >= 0) // CTCP marker ^A can be anywhere, not just immediately after the ':'
|
||||
{
|
||||
// CTCP
|
||||
msg=msg.substring(2);
|
||||
@ -451,14 +454,14 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
return s;
|
||||
}
|
||||
|
||||
if("USER".equals(command)) {
|
||||
if("USER".equalsIgnoreCase(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".equals(command)) {
|
||||
} else if ("QUIT".equalsIgnoreCase(command)) {
|
||||
return "QUIT :leaving";
|
||||
}
|
||||
|
||||
|
@ -3,15 +3,19 @@
|
||||
|
||||
<target name="all" depends="build" />
|
||||
<target name="fetchJettylib" >
|
||||
<available property="jetty.available" file="jetty-5.1.12.zip" />
|
||||
<available property="jetty.zip.available" file="jetty-5.1.12.zip" type="file" />
|
||||
<available property="jetty.zip.extracted" file="jettylib" type="dir" />
|
||||
<ant target="doFetchJettylib" />
|
||||
<ant target="doExtractJettylib" />
|
||||
</target>
|
||||
<target name="doFetchJettylib" unless="jetty.available" >
|
||||
<target name="doFetchJettylib" unless="jetty.zip.available" >
|
||||
<echo message="The libraries contained within the fetched file are from Jetty's 5.1.12" />
|
||||
<echo message="distribution (http://jetty.mortbay.org/). These are not " />
|
||||
<echo message="necessary for using I2P, but are used by some applications on top of I2P," />
|
||||
<echo message="such as the routerconsole." />
|
||||
<get src="http://mesh.dl.sourceforge.net/sourceforge/jetty/jetty-5.1.12.zip" verbose="true" dest="jetty-5.1.12.zip" />
|
||||
</target>
|
||||
<target name="doExtractJettylib" unless="jetty.zip.extracted" >
|
||||
<ant target="doExtract" />
|
||||
</target>
|
||||
<target name="doExtract">
|
||||
|
@ -2,6 +2,7 @@ package net.i2p.router.web;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.web.ConfigServiceHandler.UpdateWrapperManagerTask;
|
||||
import net.i2p.util.Log;
|
||||
@ -20,20 +21,29 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
private String _trustedKeys;
|
||||
|
||||
public static final String PROP_NEWS_URL = "router.newsURL";
|
||||
public static final String DEFAULT_NEWS_URL = "http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/news.xml?rev=HEAD";
|
||||
// public static final String DEFAULT_NEWS_URL = "http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/news.xml?rev=HEAD";
|
||||
public static final String DEFAULT_NEWS_URL = "http://complication.i2p/news.xml";
|
||||
public static final String PROP_REFRESH_FREQUENCY = "router.newsRefreshFrequency";
|
||||
public static final String DEFAULT_REFRESH_FREQUENCY = 12*60*60*1000 + "";
|
||||
public static final String PROP_UPDATE_URL = "router.updateURL";
|
||||
public static final String DEFAULT_UPDATE_URL = "http://dev.i2p.net/i2p/i2pupdate.sud";
|
||||
public static final String PROP_UPDATE_POLICY = "router.updatePolicy";
|
||||
public static final String DEFAULT_UPDATE_POLICY = "notify";
|
||||
public static final String PROP_SHOULD_PROXY = "router.updateThroughProxy";
|
||||
public static final String DEFAULT_SHOULD_PROXY = Boolean.FALSE.toString();
|
||||
public static final String DEFAULT_SHOULD_PROXY = Boolean.TRUE.toString();
|
||||
public static final String PROP_PROXY_HOST = "router.updateProxyHost";
|
||||
public static final String DEFAULT_PROXY_HOST = "localhost";
|
||||
public static final String PROP_PROXY_PORT = "router.updateProxyPort";
|
||||
public static final String DEFAULT_PROXY_PORT = "4444";
|
||||
|
||||
public static final String PROP_UPDATE_URL = "router.updateURL";
|
||||
// public static final String DEFAULT_UPDATE_URL = "http://dev.i2p.net/i2p/i2pupdate.sud";
|
||||
public static final String DEFAULT_UPDATE_URL =
|
||||
"http://amiga.i2p/i2p/i2pupdate.sud\r\n" +
|
||||
"http://stats.i2p/i2p/i2pupdate.sud\r\n" +
|
||||
"http://complication.i2p/i2p/i2pupdate.sud";
|
||||
|
||||
public static final String PROP_TRUSTED_KEYS = "router.trustedUpdateKeys";
|
||||
|
||||
|
||||
protected void processForm() {
|
||||
if ("Check for update now".equals(_action)) {
|
||||
NewsFetcher fetcher = NewsFetcher.getInstance(I2PAppContext.getGlobalContext());
|
||||
@ -52,14 +62,6 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if ( (_updateURL != null) && (_updateURL.length() > 0) ) {
|
||||
String oldURL = _context.router().getConfigSetting(PROP_UPDATE_URL);
|
||||
if ( (oldURL == null) || (!_updateURL.equals(oldURL)) ) {
|
||||
_context.router().setConfigSetting(PROP_UPDATE_URL, _updateURL);
|
||||
addFormNotice("Updating update URL to " + _updateURL);
|
||||
}
|
||||
}
|
||||
|
||||
if ( (_proxyHost != null) && (_proxyHost.length() > 0) ) {
|
||||
String oldHost = _context.router().getConfigSetting(PROP_PROXY_HOST);
|
||||
if ( (oldHost == null) || (!_proxyHost.equals(oldHost)) ) {
|
||||
@ -98,8 +100,22 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
addFormNotice("Updating update policy to " + _updatePolicy);
|
||||
}
|
||||
}
|
||||
|
||||
// should save the keys...
|
||||
|
||||
if ( (_updateURL != null) && (_updateURL.length() > 0) ) {
|
||||
String oldURL = _context.router().getConfigSetting(PROP_UPDATE_URL);
|
||||
if ( (oldURL == null) || (!_updateURL.equals(oldURL)) ) {
|
||||
_context.router().setConfigSetting(PROP_UPDATE_URL, _updateURL);
|
||||
addFormNotice("Updating update URLs.");
|
||||
}
|
||||
}
|
||||
|
||||
if ( (_trustedKeys != null) && (_trustedKeys.length() > 0) ) {
|
||||
String oldKeys = new TrustedUpdate(_context).getTrustedKeysString();
|
||||
if ( (oldKeys == null) || (!_trustedKeys.equals(oldKeys)) ) {
|
||||
_context.router().setConfigSetting(PROP_TRUSTED_KEYS, _trustedKeys);
|
||||
addFormNotice("Updating trusted keys.");
|
||||
}
|
||||
}
|
||||
|
||||
_context.router().saveConfig();
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.List;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -113,11 +112,6 @@ public class ConfigUpdateHelper {
|
||||
}
|
||||
|
||||
public String getTrustedKeys() {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
TrustedUpdate up = new TrustedUpdate(_context);
|
||||
List keys = up.getTrustedKeys();
|
||||
for (int i = 0; i < keys.size(); i++)
|
||||
buf.append((String)keys.get(i)).append('\n');
|
||||
return buf.toString();
|
||||
return new TrustedUpdate(_context).getTrustedKeysString();
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
private Log _log;
|
||||
private boolean _updateAvailable;
|
||||
private long _lastFetch;
|
||||
private String _lastModified;
|
||||
private static NewsFetcher _instance;
|
||||
//public static final synchronized NewsFetcher getInstance() { return _instance; }
|
||||
public static final synchronized NewsFetcher getInstance(I2PAppContext ctx) {
|
||||
@ -105,11 +106,12 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
proxyPort = Integer.parseInt(port);
|
||||
EepGet get = null;
|
||||
if (shouldProxy)
|
||||
get = new EepGet(_context, proxyHost, proxyPort, 10, TEMP_NEWS_FILE, newsURL);
|
||||
get = new EepGet(_context, true, proxyHost, proxyPort, 2, TEMP_NEWS_FILE, newsURL, true, null, _lastModified);
|
||||
else
|
||||
get = new EepGet(_context, 10, TEMP_NEWS_FILE, newsURL);
|
||||
get = new EepGet(_context, false, null, 0, 0, TEMP_NEWS_FILE, newsURL, true, null, _lastModified);
|
||||
get.addStatusListener(this);
|
||||
get.fetch();
|
||||
if (get.fetch())
|
||||
_lastModified = get.getLastModified();
|
||||
} catch (Throwable t) {
|
||||
_log.error("Error fetching the news", t);
|
||||
}
|
||||
@ -212,15 +214,15 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
_log.error("Failed to copy the news file!");
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Transfer complete, but no file?");
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Transfer complete, but no file? - probably 304 Not Modified");
|
||||
}
|
||||
checkForUpdates();
|
||||
}
|
||||
|
||||
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Failed to fetch the news from " + url);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Failed to fetch the news from " + url);
|
||||
File temp = new File(TEMP_NEWS_FILE);
|
||||
temp.delete();
|
||||
}
|
||||
|
@ -18,8 +18,8 @@ import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.EepGet;
|
||||
|
||||
/**
|
||||
* Handler to deal with reseed requests. This reseed from the URL
|
||||
* http://dev.i2p.net/i2pdb2/ unless the I2P configuration property "i2p.reseedURL" is
|
||||
* Handler to deal with reseed requests. This will reseed from the URL
|
||||
* http://i2pdb.tin0.de/netDb/ unless the I2P configuration property "i2p.reseedURL" is
|
||||
* set. It always writes to ./netDb/, so don't mess with that.
|
||||
*
|
||||
*/
|
||||
@ -31,7 +31,7 @@ public class ReseedHandler {
|
||||
// Reject unreasonably big files, because we download into a ByteArrayOutputStream.
|
||||
private static final long MAX_RESEED_RESPONSE_SIZE = 8 * 1024 * 1024;
|
||||
|
||||
private static final String DEFAULT_SEED_URL = "http://dev.i2p.net/i2pdb2/";
|
||||
private static final String DEFAULT_SEED_URL = "http://i2pdb.tin0.de/netDb/";
|
||||
|
||||
public ReseedHandler() {
|
||||
this(ContextHelper.getContext(null));
|
||||
@ -116,6 +116,10 @@ public class ReseedHandler {
|
||||
* save them into this router's netDb dir.
|
||||
*
|
||||
*/
|
||||
private static final String RESEED_TIPS =
|
||||
"Ensure that nothing blocks outbound HTTP, check <a href=logs.jsp>logs</a> " +
|
||||
"and if nothing helps, read FAQ about reseeding manually.";
|
||||
|
||||
private void reseed(boolean echoStatus) {
|
||||
|
||||
String seedURL = _context.getProperty("i2p.reseedURL", DEFAULT_SEED_URL);
|
||||
@ -129,8 +133,7 @@ public class ReseedHandler {
|
||||
if (contentRaw == null) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed fully (failed reading seed URL). " +
|
||||
"Ensure that nothing blocks outbound HTTP, check <a href=logs.jsp>logs</a> " +
|
||||
"and if nothing helps, read FAQ about reseeding manually.");
|
||||
RESEED_TIPS);
|
||||
// Logging deprecated here since attemptFailed() provides better info
|
||||
_log.debug("Failed reading seed URL: " + seedURL);
|
||||
return;
|
||||
@ -152,8 +155,7 @@ public class ReseedHandler {
|
||||
_log.error("Read " + contentRaw.length + " bytes from seed " + seedURL + ", but found no routerInfo URLs.");
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed fully (no routerInfo URLs at seed URL). " +
|
||||
"Ensure that nothing blocks outbound HTTP, check <a href=logs.jsp>logs</a> " +
|
||||
"and if nothing helps, read FAQ about reseeding manually.");
|
||||
RESEED_TIPS);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -177,17 +179,25 @@ public class ReseedHandler {
|
||||
}
|
||||
}
|
||||
if (echoStatus) System.out.println();
|
||||
if (errors > 0) {
|
||||
|
||||
int failPercent = 100 * errors / urls.size();
|
||||
|
||||
// Less than 10% of failures is considered success,
|
||||
// because some routerInfos will always fail.
|
||||
if ((failPercent >= 10) && (failPercent < 90)) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed partly (" + errors + " of " + urls.size() + "). " +
|
||||
"Ensure that nothing blocks outbound HTTP, check <a href=logs.jsp>logs</a> " +
|
||||
"and if nothing helps, read FAQ about reseeding manually.");
|
||||
"Last reseed failed partly (" + failPercent + "% of " + urls.size() + "). " +
|
||||
RESEED_TIPS);
|
||||
}
|
||||
if (failPercent >= 90) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed (" + failPercent + "% of " + urls.size() + "). " +
|
||||
RESEED_TIPS);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.setProperty("net.i2p.router.web.ReseedHandler.errorMessage",
|
||||
"Last reseed failed fully (exception caught). " +
|
||||
"Ensure that nothing blocks outbound HTTP, check <a href=logs.jsp>logs</a> " +
|
||||
"and if nothing helps, read FAQ about reseeding manually.");
|
||||
RESEED_TIPS);
|
||||
_log.error("Error reseeding", t);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package net.i2p.router.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
@ -102,7 +105,9 @@ public class UpdateHandler {
|
||||
private void update() {
|
||||
_startedOn = -1;
|
||||
_status = "<b>Updating</b><br />";
|
||||
String updateURL = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL, ConfigUpdateHandler.DEFAULT_UPDATE_URL);
|
||||
String updateURL = selectUpdateURL();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Selected update URL: " + updateURL);
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
String port = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT);
|
||||
@ -162,7 +167,7 @@ public class UpdateHandler {
|
||||
}
|
||||
}
|
||||
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
|
||||
_log.log(Log.CRIT, "Update did not download completely (" + bytesTransferred + " with "
|
||||
_log.log(Log.CRIT, "Update from " + url + " did not download completely (" + bytesTransferred + " with "
|
||||
+ bytesRemaining + " after " + currentAttempt + " tries)");
|
||||
|
||||
_status = "<b>Transfer failed</b><br />";
|
||||
@ -176,4 +181,21 @@ public class UpdateHandler {
|
||||
_context.router().addShutdownTask(new ConfigServiceHandler.UpdateWrapperManagerTask(Router.EXIT_GRACEFUL_RESTART));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||
}
|
||||
|
||||
private String selectUpdateURL() {
|
||||
String URLs = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL, ConfigUpdateHandler.DEFAULT_UPDATE_URL);
|
||||
StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n");
|
||||
List URLList = new ArrayList();
|
||||
while (tok.hasMoreTokens())
|
||||
URLList.add(tok.nextToken().trim());
|
||||
int size = URLList.size();
|
||||
_log.log(Log.DEBUG, "Picking update source from " + size + " candidates.");
|
||||
if (size <= 0) {
|
||||
_log.log(Log.WARN, "Update list is empty - no update available");
|
||||
return null;
|
||||
}
|
||||
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
|
||||
_log.log(Log.DEBUG, "Picked update source " + index + ".");
|
||||
return (String) URLList.get(index);
|
||||
}
|
||||
}
|
||||
|
@ -32,17 +32,17 @@
|
||||
<input type="text" size="60" name="newsURL" value="<jsp:getProperty name="updatehelper" property="newsURL" />"><br />
|
||||
Refresh frequency:
|
||||
<jsp:getProperty name="updatehelper" property="refreshFrequencySelectBox" /><br />
|
||||
Update URL:
|
||||
<input type="text" size="60" name="updateURL" value="<jsp:getProperty name="updatehelper" property="updateURL" />"><br />
|
||||
Update policy:
|
||||
<jsp:getProperty name="updatehelper" property="updatePolicySelectBox" /><br />
|
||||
Update through the eepProxy?
|
||||
<p>Update through the eepProxy?
|
||||
<jsp:getProperty name="updatehelper" property="updateThroughProxy" /><br />
|
||||
eepProxy host: <input type="text" size="10" name="proxyHost" value="<jsp:getProperty name="updatehelper" property="proxyHost" />" /><br />
|
||||
eepProxy port: <input type="text" size="4" name="proxyPort" value="<jsp:getProperty name="updatehelper" property="proxyPort" />" /><br />
|
||||
<!-- prompt for the eepproxy -->
|
||||
Trusted keys:
|
||||
<textarea name="trustedKeys" disabled="true" cols="60" rows="2"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea>
|
||||
eepProxy port: <input type="text" size="4" name="proxyPort" value="<jsp:getProperty name="updatehelper" property="proxyPort" />" /></p>
|
||||
<p>Update URLs:<br />
|
||||
<textarea name="updateURL" cols="90" rows="4"><jsp:getProperty name="updatehelper" property="updateURL" /></textarea></p>
|
||||
<p>Trusted keys:</br />
|
||||
<textarea name="trustedKeys" cols="90" rows="4"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></p>
|
||||
<br />
|
||||
<input type="submit" name="action" value="Save" />
|
||||
</form>
|
||||
</div>
|
||||
|
@ -34,7 +34,7 @@ Their XML parser requires the Sun XML APIs (JAXP) which is included in binary fo
|
||||
by their binary code license. This product includes software developed by the Apache Software Foundation
|
||||
(http://www.apache.org/). </p>
|
||||
|
||||
<p>Another application you can see on this webpage is <a href="http://www.i2p.net/i2ptunnel">I2PTunnel</a>
|
||||
<p>Another application you can see on this webpage is <a href="http://www.i2p2.i2p/i2ptunnel">I2PTunnel</a>
|
||||
(your <a href="i2ptunnel/" target="_blank">web interface</a>) - a GPL'ed application written by mihi that
|
||||
lets you tunnel normal TCP/IP traffic over I2P (such as the eepproxy and the irc proxy). There is also a
|
||||
<a href="http://susi.i2p/">susimail</a> web based mail client <a href="susimail/susimail">available</a> on
|
||||
@ -42,14 +42,14 @@ the console, which is a GPL'ed application written by susi23. The addressbook a
|
||||
<a href="http://ragnarok.i2p/">Ragnarok</a> helps maintain your hosts.txt files (see ./addressbook/ for
|
||||
more information).</p>
|
||||
|
||||
<p>The router by default also includes human's public domain <a href="http://www.i2p.net/sam">SAM</a> bridge,
|
||||
<p>The router by default also includes human's public domain <a href="http://www.i2p2.i2p/sam">SAM</a> bridge,
|
||||
which other client applications (such the <a href="http://duck.i2p/i2p-bt/">bittorrent port</a>) can use.
|
||||
There is also an optimized library for doing large number calculations - jbigi - which in turn uses the
|
||||
LGPL licensed <a href="http://swox.com/gmp/">GMP</a> library, tuned for various PC architectures. Launchers for windows users are built with <a href="http://launch4j.sourceforge.net/">Launch4J</a>, and the installer is built with <a href="http://www.izforge.com/izpack/">IzPack</a>. For
|
||||
details on other applications available, as well as their licenses, please see the
|
||||
<a href="http://www.i2p.net/licenses">license policy</a>. Source for the I2P code and most bundled
|
||||
client applications can be found on our <a href="http://www.i2p.net/download">download page</a>, and is
|
||||
in <a href="http://www.i2p.net/cvs">cvs</a>.</p>
|
||||
<a href="http://www.i2p2.i2p/licenses">license policy</a>. Source for the I2P code and most bundled
|
||||
client applications can be found on our <a href="http://www.i2p2.i2p/download">download page</a>.
|
||||
.</p>
|
||||
|
||||
<h2>Release history</h2>
|
||||
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" />
|
||||
@ -59,9 +59,8 @@ in <a href="http://www.i2p.net/cvs">cvs</a>.</p>
|
||||
<jsp:getProperty name="contenthelper" property="textContent" />
|
||||
|
||||
<p>
|
||||
A more complete list of updates can be found
|
||||
<a href="http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/history.txt?rev=HEAD">online</a>
|
||||
(<a href="http://dev.i2p/cgi-bin/cvsweb.cgi/i2p/history.txt?rev=HEAD">anonymously</a>)
|
||||
A more complete list of changes can be found
|
||||
in the history.txt file in your i2p directory.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -112,12 +112,15 @@ public class SAMHandlerFactory {
|
||||
case 1:
|
||||
handler = new SAMv1Handler(s, verMajor, verMinor, i2cpProps);
|
||||
break;
|
||||
case 2:
|
||||
handler = new SAMv2Handler(s, verMajor, verMinor, i2cpProps);
|
||||
break;
|
||||
default:
|
||||
_log.error("BUG! Trying to initialize the wrong SAM version!");
|
||||
throw new SAMException("BUG! (in handler instantiation)");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
_log.error("Error creating the v1 handler", e);
|
||||
_log.error("Error creating the handler for version "+verMajor, e);
|
||||
throw new SAMException("IOException caught during SAM handler instantiation");
|
||||
}
|
||||
return handler;
|
||||
@ -133,15 +136,16 @@ public class SAMHandlerFactory {
|
||||
|| (maxMajor == -1) || (maxMinor == -1)) {
|
||||
return null;
|
||||
}
|
||||
if (minMajor > maxMajor) {
|
||||
return null;
|
||||
} else if ((minMajor == maxMajor) && (minMinor > maxMinor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((minMajor >= 1) && (minMinor >= 0)) {
|
||||
return "1.0";
|
||||
}
|
||||
if ((minMinor >= 10) || (maxMinor >= 10)) return null ;
|
||||
|
||||
float fminVer = (float) minMajor + (float) minMinor / 10 ;
|
||||
float fmaxVer = (float) maxMajor + (float) maxMinor / 10 ;
|
||||
|
||||
|
||||
if ( ( fminVer <= 2.0 ) && ( fmaxVer >= 2.0 ) ) return "2.0" ;
|
||||
|
||||
if ( ( fminVer <= 1.0 ) && ( fmaxVer >= 1.0 ) ) return "1.0" ;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -15,14 +15,31 @@ import net.i2p.data.Destination;
|
||||
/**
|
||||
* Interface for sending streaming data to a SAM client
|
||||
*/
|
||||
|
||||
public interface SAMStreamReceiver {
|
||||
/**
|
||||
* Sends the result of a stream send operation
|
||||
*/
|
||||
public void streamSendAnswer( int id, String result, String bufferState ) throws IOException;
|
||||
|
||||
/**
|
||||
* Notifies that the outwards buffer is free for writing
|
||||
*/
|
||||
public void notifyStreamSendBufferFree( int id ) throws IOException;
|
||||
|
||||
/**
|
||||
* Notify about a new incoming connection
|
||||
*
|
||||
* @param id New connection id
|
||||
*/
|
||||
public void notifyStreamConnection(int id, Destination dest) throws IOException;
|
||||
public void notifyStreamIncomingConnection ( int id, Destination dest ) throws IOException;
|
||||
|
||||
/**
|
||||
* Notify about a new outgoing connection
|
||||
*
|
||||
* @param id New connection id
|
||||
*/
|
||||
public void notifyStreamOutgoingConnection(int id, String result, String msg) throws IOException;
|
||||
|
||||
/**
|
||||
* Send a byte array to a SAM client.
|
||||
|
@ -47,13 +47,13 @@ public class SAMStreamSession {
|
||||
|
||||
private final static Log _log = new Log(SAMStreamSession.class);
|
||||
|
||||
private final static int SOCKET_HANDLER_BUF_SIZE = 32768;
|
||||
protected final static int SOCKET_HANDLER_BUF_SIZE = 32768;
|
||||
|
||||
private SAMStreamReceiver recv = null;
|
||||
protected SAMStreamReceiver recv = null;
|
||||
|
||||
private SAMStreamSessionServer server = null;
|
||||
|
||||
private I2PSocketManager socketMgr = null;
|
||||
protected I2PSocketManager socketMgr = null;
|
||||
|
||||
private Object handlersMapLock = new Object();
|
||||
/** stream id (Long) to SAMStreamSessionSocketReader */
|
||||
@ -65,13 +65,14 @@ public class SAMStreamSession {
|
||||
private int lastNegativeId = 0;
|
||||
|
||||
// Can we create outgoing connections?
|
||||
private boolean canCreate = false;
|
||||
protected boolean canCreate = false;
|
||||
|
||||
/**
|
||||
* should we flush every time we get a STREAM SEND, or leave that up to
|
||||
* the streaming lib to decide?
|
||||
*/
|
||||
private boolean forceFlush = false;
|
||||
protected boolean forceFlush = false;
|
||||
|
||||
public static String PROP_FORCE_FLUSH = "sam.forceFlush";
|
||||
public static String DEFAULT_FORCE_FLUSH = "false";
|
||||
|
||||
@ -189,7 +190,7 @@ public class SAMStreamSession {
|
||||
* @throws InterruptedIOException if the connection timeouts
|
||||
* @throws I2PException if there's another I2P-related error
|
||||
*/
|
||||
public boolean connect(int id, String dest, Properties props) throws I2PException, ConnectException, NoRouteToHostException, DataFormatException, InterruptedIOException, SAMInvalidDirectionException {
|
||||
public boolean connect ( int id, String dest, Properties props ) throws I2PException, ConnectException, NoRouteToHostException, DataFormatException, InterruptedIOException, SAMInvalidDirectionException, IOException {
|
||||
if (!canCreate) {
|
||||
_log.debug("Trying to create an outgoing connection using a receive-only session");
|
||||
throw new SAMInvalidDirectionException("Trying to create connections through a receive-only session");
|
||||
@ -208,10 +209,15 @@ public class SAMStreamSession {
|
||||
opts.setConnectTimeout(60 * 1000);
|
||||
|
||||
_log.debug("Connecting new I2PSocket...");
|
||||
|
||||
// blocking connection (SAMv1)
|
||||
|
||||
I2PSocket i2ps = socketMgr.connect(d, opts);
|
||||
|
||||
createSocketHandler(i2ps, id);
|
||||
|
||||
recv.notifyStreamOutgoingConnection ( id, "OK", null );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -277,7 +283,7 @@ public class SAMStreamSession {
|
||||
*
|
||||
* @return An id associated to the socket handler
|
||||
*/
|
||||
private int createSocketHandler(I2PSocket s, int id) {
|
||||
protected int createSocketHandler ( I2PSocket s, int id ) {
|
||||
SAMStreamSessionSocketReader reader = null;
|
||||
StreamSender sender = null;
|
||||
if (id == 0) {
|
||||
@ -285,8 +291,8 @@ public class SAMStreamSession {
|
||||
}
|
||||
|
||||
try {
|
||||
reader = new SAMStreamSessionSocketReader(s, id);
|
||||
sender = new StreamSender(s, id);
|
||||
reader = newSAMStreamSessionSocketReader(s, id);
|
||||
sender = newStreamSender(s, id);
|
||||
} catch (IOException e) {
|
||||
_log.error("IOException when creating SAM STREAM session socket handler", e);
|
||||
recv.stopStreamReceiving();
|
||||
@ -318,7 +324,7 @@ public class SAMStreamSession {
|
||||
*
|
||||
* @param id Handler id
|
||||
*/
|
||||
private SAMStreamSessionSocketReader getSocketReader(int id) {
|
||||
protected SAMStreamSessionSocketReader getSocketReader ( int id ) {
|
||||
synchronized (handlersMapLock) {
|
||||
return (SAMStreamSessionSocketReader)handlersMap.get(new Integer(id));
|
||||
}
|
||||
@ -334,7 +340,7 @@ public class SAMStreamSession {
|
||||
*
|
||||
* @param id Handler id
|
||||
*/
|
||||
private boolean checkSocketHandlerId(int id) {
|
||||
protected boolean checkSocketHandlerId ( int id ) {
|
||||
synchronized (handlersMapLock) {
|
||||
return (!(handlersMap.get(new Integer(id)) == null));
|
||||
}
|
||||
@ -345,7 +351,7 @@ public class SAMStreamSession {
|
||||
*
|
||||
* @param id Handler id to be removed
|
||||
*/
|
||||
private void removeSocketHandler(int id) {
|
||||
protected void removeSocketHandler ( int id ) {
|
||||
SAMStreamSessionSocketReader reader = null;
|
||||
StreamSender sender = null;
|
||||
|
||||
@ -446,7 +452,8 @@ public class SAMStreamSession {
|
||||
}
|
||||
|
||||
_log.debug("New connection id: " + id);
|
||||
recv.notifyStreamConnection(id, i2ps.getPeerDestination());
|
||||
|
||||
recv.notifyStreamIncomingConnection ( id, i2ps.getPeerDestination() );
|
||||
} catch (I2PException e) {
|
||||
_log.debug("Caught I2PException", e);
|
||||
break;
|
||||
@ -469,29 +476,62 @@ public class SAMStreamSession {
|
||||
|
||||
}
|
||||
|
||||
|
||||
boolean setReceiveLimit ( int id, long limit, boolean nolimit )
|
||||
{
|
||||
_log.debug ( "Protocol v1 does not support a receive limit for streams" );
|
||||
return false ;
|
||||
}
|
||||
|
||||
/**
|
||||
* SAM STREAM socket handler, running in its own thread. It forwards
|
||||
* SAM STREAM socket reader, running in its own thread. It forwards
|
||||
* forward data to/from an I2P socket.
|
||||
*
|
||||
* @author human
|
||||
*/
|
||||
public class SAMStreamSessionSocketReader implements Runnable {
|
||||
|
||||
private I2PSocket i2pSocket = null;
|
||||
protected I2PSocket i2pSocket = null;
|
||||
|
||||
private Object runningLock = new Object();
|
||||
private boolean stillRunning = true;
|
||||
protected Object runningLock = new Object();
|
||||
|
||||
protected boolean stillRunning = true;
|
||||
|
||||
protected int id;
|
||||
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* Create a new SAM STREAM session socket reader
|
||||
*
|
||||
* @param s Socket to be handled
|
||||
* @param id Unique id assigned to the handler
|
||||
*/
|
||||
public SAMStreamSessionSocketReader(I2PSocket s, int id) throws IOException {
|
||||
_log.debug("Instantiating new SAM STREAM session socket handler");
|
||||
public SAMStreamSessionSocketReader ( I2PSocket s, int id ) throws IOException {}
|
||||
|
||||
/**
|
||||
* Stop a SAM STREAM session socket reader thread immediately.
|
||||
*/
|
||||
public void stopRunning() {}
|
||||
|
||||
public void run() {}
|
||||
|
||||
}
|
||||
|
||||
protected SAMStreamSessionSocketReader
|
||||
newSAMStreamSessionSocketReader ( I2PSocket s, int id ) throws IOException {
|
||||
return new SAMv1StreamSessionSocketReader ( s, id );
|
||||
}
|
||||
|
||||
public class SAMv1StreamSessionSocketReader extends SAMStreamSessionSocketReader {
|
||||
/**
|
||||
* Create a new SAM STREAM session socket reader
|
||||
*
|
||||
* @param s Socket to be handled
|
||||
* @param id Unique id assigned to the handler
|
||||
*/
|
||||
|
||||
public SAMv1StreamSessionSocketReader ( I2PSocket s, int id ) throws IOException {
|
||||
super(s, id);
|
||||
_log.debug("Instantiating new SAM STREAM session socket reader");
|
||||
|
||||
i2pSocket = s;
|
||||
this.id = id;
|
||||
@ -507,6 +547,7 @@ public class SAMStreamSession {
|
||||
if (stillRunning) {
|
||||
stillRunning = false;
|
||||
}
|
||||
runningLock.notifyAll() ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -558,7 +599,40 @@ public class SAMStreamSession {
|
||||
* Lets us push data through the stream without blocking, (even after exceeding
|
||||
* the I2PSocket's buffer)
|
||||
*/
|
||||
private class StreamSender implements Runnable {
|
||||
protected class StreamSender implements Runnable {
|
||||
public StreamSender ( I2PSocket s, int id ) throws IOException {}
|
||||
|
||||
/**
|
||||
* Send bytes through the SAM STREAM session socket sender
|
||||
*
|
||||
* @param data Data to be sent
|
||||
*
|
||||
* @throws IOException if the client didnt provide enough data
|
||||
*/
|
||||
public void sendBytes ( InputStream in, int size ) throws IOException {}
|
||||
|
||||
|
||||
/**
|
||||
* Stop a SAM STREAM session socket sender thread immediately
|
||||
*
|
||||
*/
|
||||
public void stopRunning() {}
|
||||
|
||||
/**
|
||||
* Stop a SAM STREAM session socket sender gracefully: stop the
|
||||
* sender thread once all pending data has been sent.
|
||||
*/
|
||||
public void shutDownGracefully() {}
|
||||
|
||||
public void run() {}
|
||||
}
|
||||
|
||||
protected StreamSender newStreamSender ( I2PSocket s, int id ) throws IOException {
|
||||
return new v1StreamSender ( s, id ) ;
|
||||
}
|
||||
|
||||
protected class v1StreamSender extends StreamSender
|
||||
{
|
||||
private List _data;
|
||||
private int _id;
|
||||
private ByteCache _cache;
|
||||
@ -567,7 +641,8 @@ public class SAMStreamSession {
|
||||
private Object runningLock = new Object();
|
||||
private I2PSocket i2pSocket = null;
|
||||
|
||||
public StreamSender(I2PSocket s, int id) throws IOException {
|
||||
public v1StreamSender ( I2PSocket s, int id ) throws IOException {
|
||||
super ( s, id );
|
||||
_data = new ArrayList(1);
|
||||
_id = id;
|
||||
_cache = ByteCache.getInstance(4, 32*1024);
|
||||
|
@ -35,6 +35,8 @@ import net.i2p.util.Log;
|
||||
* @author human
|
||||
*/
|
||||
public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramReceiver, SAMStreamReceiver {
|
||||
protected int verMajorId = 1;
|
||||
protected int verMinorId = 0;
|
||||
|
||||
private final static Log _log = new Log(SAMv1Handler.class);
|
||||
|
||||
@ -42,7 +44,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
|
||||
private SAMRawSession rawSession = null;
|
||||
private SAMDatagramSession datagramSession = null;
|
||||
private SAMStreamSession streamSession = null;
|
||||
protected SAMStreamSession streamSession = null;
|
||||
|
||||
private long _id;
|
||||
private static volatile long __id = 0;
|
||||
@ -74,11 +76,15 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
_id = ++__id;
|
||||
_log.debug("SAM version 1 handler instantiated");
|
||||
|
||||
if ((this.verMajor != 1) || (this.verMinor != 0)) {
|
||||
if ( ! verifVersion() ) {
|
||||
throw new SAMException("BUG! Wrong protocol version!");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean verifVersion() {
|
||||
return ( verMajor == 1 && verMinor == 0 ) ;
|
||||
}
|
||||
|
||||
public void handle() {
|
||||
String msg = null;
|
||||
String domain = null;
|
||||
@ -248,7 +254,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
props.remove("DIRECTION");
|
||||
|
||||
streamSession = new SAMStreamSession(destKeystream, dir,props,this);
|
||||
streamSession = newSAMStreamSession(destKeystream, dir,props);
|
||||
} else {
|
||||
_log.debug("Unrecognized SESSION STYLE: \"" + style +"\"");
|
||||
return writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"Unrecognized SESSION STYLE\"\n");
|
||||
@ -275,6 +281,13 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SAMStreamSession newSAMStreamSession(String destKeystream, String direction, Properties props )
|
||||
throws IOException, DataFormatException, SAMException
|
||||
{
|
||||
return new SAMStreamSession(destKeystream, direction, props, this) ;
|
||||
}
|
||||
|
||||
/* Parse and execute a DEST message*/
|
||||
private boolean execDestMessage(String opcode, Properties props) {
|
||||
|
||||
@ -489,7 +502,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
|
||||
/* Parse and execute a STREAM message */
|
||||
private boolean execStreamMessage(String opcode, Properties props) {
|
||||
protected boolean execStreamMessage(String opcode, Properties props) {
|
||||
if (streamSession == null) {
|
||||
_log.error("STREAM message received, but no STREAM session exists");
|
||||
return false;
|
||||
@ -508,7 +521,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
}
|
||||
|
||||
private boolean execStreamSend(Properties props) {
|
||||
protected boolean execStreamSend(Properties props) {
|
||||
if (props == null) {
|
||||
_log.debug("No parameters specified in STREAM SEND message");
|
||||
return false;
|
||||
@ -570,7 +583,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
}
|
||||
|
||||
private boolean execStreamConnect(Properties props) {
|
||||
protected boolean execStreamConnect(Properties props) {
|
||||
if (props == null) {
|
||||
_log.debug("No parameters specified in STREAM CONNECT message");
|
||||
return false;
|
||||
@ -604,39 +617,38 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
props.remove("DESTINATION");
|
||||
|
||||
try {
|
||||
if (!streamSession.connect(id, dest, props)) {
|
||||
_log.debug("STREAM connection failed");
|
||||
return false;
|
||||
try {
|
||||
if (!streamSession.connect(id, dest, props)) {
|
||||
_log.debug("STREAM connection failed");
|
||||
return false;
|
||||
}
|
||||
} catch (DataFormatException e) {
|
||||
_log.debug("Invalid destination in STREAM CONNECT message");
|
||||
notifyStreamOutgoingConnection ( id, "INVALID_KEY", null );
|
||||
} catch (SAMInvalidDirectionException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
notifyStreamOutgoingConnection ( id, "INVALID_DIRECTION", null );
|
||||
} catch (ConnectException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
notifyStreamOutgoingConnection ( id, "CONNECTION_REFUSED", null );
|
||||
} catch (NoRouteToHostException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
notifyStreamOutgoingConnection ( id, "CANT_REACH_PEER", null );
|
||||
} catch (InterruptedIOException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
notifyStreamOutgoingConnection ( id, "TIMEOUT", null );
|
||||
} catch (I2PException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
notifyStreamOutgoingConnection ( id, "I2P_ERROR", null );
|
||||
}
|
||||
return writeString("STREAM STATUS RESULT=OK ID=" + id + "\n");
|
||||
} catch (DataFormatException e) {
|
||||
_log.debug("Invalid destination in STREAM CONNECT message");
|
||||
return writeString("STREAM STATUS RESULT=INVALID_KEY ID="
|
||||
+ id + "\n");
|
||||
} catch (SAMInvalidDirectionException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
return writeString("STREAM STATUS RESULT=INVALID_DIRECTION ID="
|
||||
+ id + "\n");
|
||||
} catch (ConnectException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
return writeString("STREAM STATUS RESULT=CONNECTION_REFUSED ID="
|
||||
+ id + "\n");
|
||||
} catch (NoRouteToHostException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
return writeString("STREAM STATUS RESULT=CANT_REACH_PEER ID="
|
||||
+ id + "\n");
|
||||
} catch (InterruptedIOException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
return writeString("STREAM STATUS RESULT=TIMEOUT ID="
|
||||
+ id + "\n");
|
||||
} catch (I2PException e) {
|
||||
_log.debug("STREAM CONNECT failed: " + e.getMessage());
|
||||
return writeString("STREAM STATUS RESULT=I2P_ERROR ID="
|
||||
+ id + "\n");
|
||||
} catch (IOException e) {
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
private boolean execStreamClose(Properties props) {
|
||||
protected boolean execStreamClose(Properties props) {
|
||||
if (props == null) {
|
||||
_log.debug("No parameters specified in STREAM CLOSE message");
|
||||
return false;
|
||||
@ -745,7 +757,41 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
|
||||
// SAMStreamReceiver implementation
|
||||
public void notifyStreamConnection(int id, Destination d) throws IOException {
|
||||
|
||||
public void streamSendAnswer( int id, String result, String bufferState ) throws IOException
|
||||
{
|
||||
if ( streamSession == null )
|
||||
{
|
||||
_log.error ( "BUG! Want to answer to stream SEND, but session is null!" );
|
||||
throw new NullPointerException ( "BUG! STREAM session is null!" );
|
||||
}
|
||||
|
||||
if ( !writeString ( "STREAM SEND ID=" + id
|
||||
+ " RESULT=" + result
|
||||
+ " STATE=" + bufferState
|
||||
+ "\n" ) )
|
||||
{
|
||||
throw new IOException ( "Error notifying connection to SAM client" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void notifyStreamSendBufferFree( int id ) throws IOException
|
||||
{
|
||||
if ( streamSession == null )
|
||||
{
|
||||
_log.error ( "BUG! Stream outgoing buffer is free, but session is null!" );
|
||||
throw new NullPointerException ( "BUG! STREAM session is null!" );
|
||||
}
|
||||
|
||||
if ( !writeString ( "STREAM READY_TO_SEND ID=" + id + "\n" ) )
|
||||
{
|
||||
throw new IOException ( "Error notifying connection to SAM client" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void notifyStreamIncomingConnection(int id, Destination d) throws IOException {
|
||||
if (streamSession == null) {
|
||||
_log.error("BUG! Received stream connection, but session is null!");
|
||||
throw new NullPointerException("BUG! STREAM session is null!");
|
||||
@ -758,6 +804,28 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyStreamOutgoingConnection ( int id, String result, String msg ) throws IOException
|
||||
{
|
||||
if ( streamSession == null )
|
||||
{
|
||||
_log.error ( "BUG! Received stream connection, but session is null!" );
|
||||
throw new NullPointerException ( "BUG! STREAM session is null!" );
|
||||
}
|
||||
|
||||
String msgString = "" ;
|
||||
|
||||
if ( msg != null ) msgString = " MESSAGE=\"" + msg + "\"";
|
||||
|
||||
if ( !writeString ( "STREAM STATUS RESULT="
|
||||
+ result
|
||||
+ " ID=" + id
|
||||
+ msgString
|
||||
+ "\n" ) )
|
||||
{
|
||||
throw new IOException ( "Error notifying connection to SAM client" );
|
||||
}
|
||||
}
|
||||
|
||||
public void receiveStreamBytes(int id, byte data[], int len) throws IOException {
|
||||
if (streamSession == null) {
|
||||
_log.error("Received stream bytes, but session is null!");
|
||||
|
196
apps/sam/java/src/net/i2p/sam/SAMv2Handler.java
Normal file
196
apps/sam/java/src/net/i2p/sam/SAMv2Handler.java
Normal file
@ -0,0 +1,196 @@
|
||||
package net.i2p.sam;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by human in 2004 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ConnectException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.Socket;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Class able to handle a SAM version 2 client connection.
|
||||
*
|
||||
* @author mkvore
|
||||
*/
|
||||
|
||||
public class SAMv2Handler extends SAMv1Handler implements SAMRawReceiver, SAMDatagramReceiver, SAMStreamReceiver
|
||||
{
|
||||
|
||||
private final static Log _log = new Log ( SAMv2Handler.class );
|
||||
|
||||
|
||||
/**
|
||||
* Create a new SAM version 2 handler. This constructor expects
|
||||
* that the SAM HELLO message has been still answered (and
|
||||
* stripped) from the socket input stream.
|
||||
*
|
||||
* @param s Socket attached to a SAM client
|
||||
* @param verMajor SAM major version to manage (should be 2)
|
||||
* @param verMinor SAM minor version to manage
|
||||
*/
|
||||
public SAMv2Handler ( Socket s, int verMajor, int verMinor ) throws SAMException, IOException
|
||||
{
|
||||
this ( s, verMajor, verMinor, new Properties() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SAM version 2 handler. This constructor expects
|
||||
* that the SAM HELLO message has been still answered (and
|
||||
* stripped) from the socket input stream.
|
||||
*
|
||||
* @param s Socket attached to a SAM client
|
||||
* @param verMajor SAM major version to manage (should be 2)
|
||||
* @param verMinor SAM minor version to manage
|
||||
* @param i2cpProps properties to configure the I2CP connection (host, port, etc)
|
||||
*/
|
||||
|
||||
public SAMv2Handler ( Socket s, int verMajor, int verMinor, Properties i2cpProps ) throws SAMException, IOException
|
||||
{
|
||||
super ( s, verMajor, verMinor, i2cpProps );
|
||||
}
|
||||
|
||||
public boolean verifVersion()
|
||||
{
|
||||
return (verMajor == 2 && verMinor == 0) ;
|
||||
}
|
||||
|
||||
SAMStreamSession newSAMStreamSession(String destKeystream, String direction, Properties props )
|
||||
throws IOException, DataFormatException, SAMException
|
||||
{
|
||||
return new SAMv2StreamSession(destKeystream, direction, props, this) ;
|
||||
}
|
||||
|
||||
|
||||
/* Parse and execute a STREAM message */
|
||||
protected boolean execStreamMessage ( String opcode, Properties props )
|
||||
{
|
||||
if ( streamSession == null )
|
||||
{
|
||||
_log.error ( "STREAM message received, but no STREAM session exists" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( opcode.equals ( "SEND" ) )
|
||||
{
|
||||
return execStreamSend ( props );
|
||||
}
|
||||
else if ( opcode.equals ( "CONNECT" ) )
|
||||
{
|
||||
return execStreamConnect ( props );
|
||||
}
|
||||
else if ( opcode.equals ( "CLOSE" ) )
|
||||
{
|
||||
return execStreamClose ( props );
|
||||
}
|
||||
else if ( opcode.equals ( "RECEIVE") )
|
||||
{
|
||||
return execStreamReceive( props );
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.debug ( "Unrecognized RAW message opcode: \""
|
||||
+ opcode + "\"" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private boolean execStreamReceive ( Properties props )
|
||||
{
|
||||
if ( props == null )
|
||||
{
|
||||
_log.debug ( "No parameters specified in STREAM RECEIVE message" );
|
||||
return false;
|
||||
}
|
||||
|
||||
int id;
|
||||
|
||||
{
|
||||
String strid = props.getProperty ( "ID" );
|
||||
|
||||
if ( strid == null )
|
||||
{
|
||||
_log.debug ( "ID not specified in STREAM RECEIVE message" );
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
id = Integer.parseInt ( strid );
|
||||
}
|
||||
catch ( NumberFormatException e )
|
||||
{
|
||||
_log.debug ( "Invalid STREAM RECEIVE ID specified: " + strid );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean nolimit = false;
|
||||
|
||||
long limit = 0;
|
||||
{
|
||||
String strsize = props.getProperty ( "LIMIT" );
|
||||
|
||||
if ( strsize == null )
|
||||
{
|
||||
_log.debug ( "Limit not specified in STREAM RECEIVE message" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( strsize.equals( "NONE" ) )
|
||||
{
|
||||
nolimit = true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
limit = Long.parseLong ( strsize );
|
||||
}
|
||||
catch ( NumberFormatException e )
|
||||
{
|
||||
_log.debug ( "Invalid STREAM RECEIVE size specified: " + strsize );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( limit < 0 )
|
||||
{
|
||||
_log.debug ( "Specified limit (" + limit
|
||||
+ ") is out of protocol limits" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
streamSession.setReceiveLimit ( id, limit, nolimit ) ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
574
apps/sam/java/src/net/i2p/sam/SAMv2StreamSession.java
Normal file
574
apps/sam/java/src/net/i2p/sam/SAMv2StreamSession.java
Normal file
@ -0,0 +1,574 @@
|
||||
package net.i2p.sam;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by human in 2004 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ConnectException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.streaming.I2PServerSocket;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
import net.i2p.client.streaming.I2PSocketOptions;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* SAMv2 STREAM session class.
|
||||
*
|
||||
* @author mkvore
|
||||
*/
|
||||
|
||||
public class SAMv2StreamSession extends SAMStreamSession
|
||||
{
|
||||
|
||||
private final static Log _log = new Log ( SAMv2StreamSession.class );
|
||||
|
||||
/**
|
||||
* Create a new SAM STREAM session.
|
||||
*
|
||||
* @param dest Base64-encoded destination (private key)
|
||||
* @param dir Session direction ("RECEIVE", "CREATE" or "BOTH")
|
||||
* @param props Properties to setup the I2P session
|
||||
* @param recv Object that will receive incoming data
|
||||
*/
|
||||
public SAMv2StreamSession ( String dest, String dir, Properties props,
|
||||
SAMStreamReceiver recv ) throws IOException, DataFormatException, SAMException
|
||||
{
|
||||
super ( dest, dir, props, recv );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SAM STREAM session.
|
||||
*
|
||||
* @param destStream Input stream containing the destination keys
|
||||
* @param dir Session direction ("RECEIVE", "CREATE" or "BOTH")
|
||||
* @param props Properties to setup the I2P session
|
||||
* @param recv Object that will receive incoming data
|
||||
*/
|
||||
public SAMv2StreamSession ( InputStream destStream, String dir,
|
||||
Properties props, SAMStreamReceiver recv ) throws IOException, DataFormatException, SAMException
|
||||
{
|
||||
super ( destStream, dir, props, recv );
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the SAM STREAM session to the specified Destination
|
||||
*
|
||||
* @param id Unique id for the connection
|
||||
* @param dest Base64-encoded Destination to connect to
|
||||
* @param props Options to be used for connection
|
||||
*
|
||||
* @throws DataFormatException if the destination is not valid
|
||||
* @throws SAMInvalidDirectionException if trying to connect through a
|
||||
* receive-only session
|
||||
* @return true if the communication with the SAM client is ok
|
||||
*/
|
||||
|
||||
public boolean connect ( int id, String dest, Properties props )
|
||||
throws DataFormatException, SAMInvalidDirectionException
|
||||
{
|
||||
if ( !canCreate )
|
||||
{
|
||||
_log.debug ( "Trying to create an outgoing connection using a receive-only session" );
|
||||
throw new SAMInvalidDirectionException ( "Trying to create connections through a receive-only session" );
|
||||
}
|
||||
|
||||
if ( checkSocketHandlerId ( id ) )
|
||||
{
|
||||
_log.debug ( "The specified id (" + id + ") is already in use" );
|
||||
return false ;
|
||||
}
|
||||
|
||||
Destination d = new Destination();
|
||||
|
||||
d.fromBase64 ( dest );
|
||||
|
||||
I2PSocketOptions opts = socketMgr.buildOptions ( props );
|
||||
|
||||
if ( props.getProperty ( I2PSocketOptions.PROP_CONNECT_TIMEOUT ) == null )
|
||||
opts.setConnectTimeout ( 60 * 1000 );
|
||||
|
||||
_log.debug ( "Connecting new I2PSocket..." );
|
||||
|
||||
|
||||
// non-blocking connection (SAMv2)
|
||||
|
||||
StreamConnector connector ;
|
||||
|
||||
connector = new StreamConnector ( id, d, opts );
|
||||
|
||||
I2PThread connectThread = new I2PThread ( connector, "StreamConnector" + id ) ;
|
||||
|
||||
connectThread.start() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* SAM STREAM socket connecter, running in its own thread.
|
||||
*
|
||||
* @author mkvore
|
||||
*/
|
||||
|
||||
public class StreamConnector implements Runnable
|
||||
{
|
||||
|
||||
private Object runningLock = new Object();
|
||||
private boolean stillRunning = true;
|
||||
|
||||
private int id;
|
||||
private Destination dest ;
|
||||
private I2PSocketOptions opts ;
|
||||
|
||||
/**
|
||||
* Create a new SAM STREAM session socket reader
|
||||
*
|
||||
* @param id Unique id assigned to the handler
|
||||
* @param dest Destination to reach
|
||||
* @param opts Socket options (I2PSocketOptions)
|
||||
*/
|
||||
|
||||
|
||||
public StreamConnector ( int id, Destination dest, I2PSocketOptions opts )// throws IOException
|
||||
{
|
||||
_log.debug ( "Instantiating new SAM STREAM connector" );
|
||||
|
||||
this.id = id ;
|
||||
this.opts = opts ;
|
||||
this.dest = dest ;
|
||||
}
|
||||
|
||||
|
||||
public void run()
|
||||
{
|
||||
_log.debug ( "run() called for socket connector " + id );
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
I2PSocket i2ps = socketMgr.connect ( dest, opts );
|
||||
|
||||
createSocketHandler ( i2ps, id );
|
||||
|
||||
recv.notifyStreamOutgoingConnection ( id, "OK", null );
|
||||
}
|
||||
|
||||
catch ( DataFormatException e )
|
||||
{
|
||||
_log.debug ( "Invalid destination in STREAM CONNECT message" );
|
||||
recv.notifyStreamOutgoingConnection ( id, "INVALID_KEY", e.getMessage() );
|
||||
}
|
||||
catch ( ConnectException e )
|
||||
{
|
||||
_log.debug ( "STREAM CONNECT failed: " + e.getMessage() );
|
||||
recv.notifyStreamOutgoingConnection ( id, "CONNECTION_REFUSED", e.getMessage() );
|
||||
}
|
||||
catch ( NoRouteToHostException e )
|
||||
{
|
||||
_log.debug ( "STREAM CONNECT failed: " + e.getMessage() );
|
||||
recv.notifyStreamOutgoingConnection ( id, "CANT_REACH_PEER", e.getMessage() );
|
||||
}
|
||||
catch ( InterruptedIOException e )
|
||||
{
|
||||
_log.debug ( "STREAM CONNECT failed: " + e.getMessage() );
|
||||
recv.notifyStreamOutgoingConnection ( id, "TIMEOUT", e.getMessage() );
|
||||
}
|
||||
catch ( I2PException e )
|
||||
{
|
||||
_log.debug ( "STREAM CONNECT failed: " + e.getMessage() );
|
||||
recv.notifyStreamOutgoingConnection ( id, "I2P_ERROR", e.getMessage() );
|
||||
}
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
_log.debug ( "Error sending disconnection notice for handler "
|
||||
+ id, e );
|
||||
}
|
||||
|
||||
_log.debug ( "Shutting down SAM STREAM session connector " + id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lets us push data through the stream without blocking, (even after exceeding
|
||||
* the I2PSocket's buffer)
|
||||
*/
|
||||
|
||||
protected StreamSender newStreamSender ( I2PSocket s, int id ) throws IOException
|
||||
{
|
||||
return new v2StreamSender ( s, id ) ;
|
||||
}
|
||||
|
||||
protected SAMStreamSessionSocketReader
|
||||
newSAMStreamSessionSocketReader(I2PSocket s, int id ) throws IOException
|
||||
{
|
||||
return new SAMv2StreamSessionSocketReader(s,id);
|
||||
}
|
||||
|
||||
protected class v2StreamSender extends StreamSender
|
||||
|
||||
{
|
||||
private List _data;
|
||||
private int _dataSize;
|
||||
private int _id;
|
||||
private ByteCache _cache;
|
||||
private OutputStream _out = null;
|
||||
private boolean _stillRunning, _shuttingDownGracefully;
|
||||
private Object runningLock = new Object();
|
||||
private I2PSocket i2pSocket = null;
|
||||
|
||||
public v2StreamSender ( I2PSocket s, int id ) throws IOException
|
||||
{
|
||||
super ( s, id );
|
||||
_data = new ArrayList ( 1 );
|
||||
_dataSize = 0;
|
||||
_id = id;
|
||||
_cache = ByteCache.getInstance ( 10, 32 * 1024 );
|
||||
_out = s.getOutputStream();
|
||||
_stillRunning = true;
|
||||
_shuttingDownGracefully = false;
|
||||
i2pSocket = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send bytes through the SAM STREAM session socket sender
|
||||
*
|
||||
* @param data Data to be sent
|
||||
*
|
||||
* @throws IOException if the client didnt provide enough data
|
||||
*/
|
||||
public void sendBytes ( InputStream in, int size ) throws IOException
|
||||
{
|
||||
if ( _log.shouldLog ( Log.DEBUG ) )
|
||||
_log.debug ( "Handler " + _id + ": sending " + size + " bytes" );
|
||||
|
||||
ByteArray ba = _cache.acquire();
|
||||
|
||||
int read = DataHelper.read ( in, ba.getData(), 0, size );
|
||||
|
||||
if ( read != size )
|
||||
throw new IOException ( "Insufficient data from the SAM client (" + read + "/" + size + ")" );
|
||||
|
||||
ba.setValid ( read );
|
||||
|
||||
synchronized ( _data )
|
||||
{
|
||||
if ( _dataSize >= SOCKET_HANDLER_BUF_SIZE )
|
||||
{
|
||||
_cache.release ( ba, false );
|
||||
recv.streamSendAnswer ( _id, "FAILED", "BUFFER_FULL" ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dataSize += size ;
|
||||
_data.add ( ba );
|
||||
_data.notifyAll();
|
||||
|
||||
if ( _dataSize >= SOCKET_HANDLER_BUF_SIZE )
|
||||
{
|
||||
recv.streamSendAnswer ( _id, "OK", "BUFFER_FULL" ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
recv.streamSendAnswer ( _id, "OK", "READY" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a SAM STREAM session socket sender thread immediately
|
||||
*
|
||||
*/
|
||||
public void stopRunning()
|
||||
{
|
||||
_log.debug ( "stopRunning() invoked on socket sender " + _id );
|
||||
|
||||
synchronized ( runningLock )
|
||||
{
|
||||
if ( _stillRunning )
|
||||
{
|
||||
_stillRunning = false;
|
||||
|
||||
try
|
||||
{
|
||||
i2pSocket.close();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
_log.debug ( "Caught IOException", e );
|
||||
}
|
||||
|
||||
synchronized ( _data )
|
||||
{
|
||||
_data.clear();
|
||||
_data.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a SAM STREAM session socket sender gracefully: stop the
|
||||
* sender thread once all pending data has been sent.
|
||||
*/
|
||||
public void shutDownGracefully()
|
||||
{
|
||||
_log.debug ( "shutDownGracefully() invoked on socket sender " + _id );
|
||||
_shuttingDownGracefully = true;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
_log.debug ( "run() called for socket sender " + _id );
|
||||
ByteArray data = null;
|
||||
|
||||
while ( _stillRunning )
|
||||
{
|
||||
data = null;
|
||||
|
||||
try
|
||||
{
|
||||
synchronized ( _data )
|
||||
{
|
||||
if ( _data.size() > 0 )
|
||||
{
|
||||
int formerSize = _dataSize ;
|
||||
data = ( ByteArray ) _data.remove ( 0 );
|
||||
_dataSize -= data.getValid();
|
||||
|
||||
if ( ( formerSize >= SOCKET_HANDLER_BUF_SIZE ) && ( _dataSize < SOCKET_HANDLER_BUF_SIZE ) )
|
||||
recv.notifyStreamSendBufferFree ( _id );
|
||||
}
|
||||
else if ( _shuttingDownGracefully )
|
||||
{
|
||||
/* No data left and shutting down gracefully?
|
||||
If so, stop the sender. */
|
||||
stopRunning();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for data. */
|
||||
_data.wait ( 5000 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( data != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
_out.write ( data.getData(), 0, data.getValid() );
|
||||
|
||||
if ( forceFlush )
|
||||
{
|
||||
// i dont like doing this, but it clears the buffer issues
|
||||
_out.flush();
|
||||
}
|
||||
}
|
||||
catch ( IOException ioe )
|
||||
{
|
||||
// ok, the stream failed, but the SAM client didn't
|
||||
|
||||
if ( _log.shouldLog ( Log.WARN ) )
|
||||
_log.warn ( "Stream failed", ioe );
|
||||
|
||||
removeSocketHandler ( _id );
|
||||
|
||||
stopRunning();
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cache.release ( data, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( InterruptedException ie ) {}
|
||||
catch ( IOException e ) {}}
|
||||
|
||||
synchronized ( _data )
|
||||
{
|
||||
_data.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send bytes through a SAM STREAM session.
|
||||
*
|
||||
* @param data Bytes to be sent
|
||||
*
|
||||
* @return True if the data was queued for sending, false otherwise
|
||||
*/
|
||||
public boolean setReceiveLimit ( int id, long limit, boolean nolimit )
|
||||
{
|
||||
SAMStreamSessionSocketReader reader = getSocketReader ( id );
|
||||
|
||||
if ( reader == null )
|
||||
{
|
||||
if ( _log.shouldLog ( Log.WARN ) )
|
||||
_log.warn ( "Trying to set a limit to a nonexistent reader " + id );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
( (SAMv2StreamSessionSocketReader) reader).setLimit ( limit, nolimit );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SAM STREAM socket reader, running in its own thread. It forwards
|
||||
* forward data to/from an I2P socket.
|
||||
*
|
||||
* @author human
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class SAMv2StreamSessionSocketReader extends SAMv1StreamSessionSocketReader
|
||||
{
|
||||
|
||||
protected boolean nolimit ;
|
||||
protected long limit ;
|
||||
protected long totalReceived ;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new SAM STREAM session socket reader
|
||||
*
|
||||
* @param s Socket to be handled
|
||||
* @param id Unique id assigned to the handler
|
||||
*/
|
||||
public SAMv2StreamSessionSocketReader ( I2PSocket s, int id ) throws IOException
|
||||
{
|
||||
super ( s, id );
|
||||
nolimit = false ;
|
||||
limit = 0 ;
|
||||
totalReceived = 0 ;
|
||||
}
|
||||
|
||||
public void setLimit ( long limit, boolean nolimit )
|
||||
{
|
||||
synchronized (runningLock)
|
||||
{
|
||||
this.limit = limit ;
|
||||
this.nolimit = nolimit ;
|
||||
runningLock.notify() ;
|
||||
}
|
||||
_log.debug ( "new limit set for socket reader " + id + " : " + (nolimit ? "NOLIMIT" : limit + " bytes" ) );
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
_log.debug ( "run() called for socket reader " + id );
|
||||
|
||||
int read = -1;
|
||||
byte[] data = new byte[SOCKET_HANDLER_BUF_SIZE];
|
||||
|
||||
try
|
||||
{
|
||||
InputStream in = i2pSocket.getInputStream();
|
||||
|
||||
while ( stillRunning )
|
||||
{
|
||||
synchronized (runningLock)
|
||||
{
|
||||
while ( stillRunning && ( !nolimit && totalReceived >= limit) )
|
||||
{
|
||||
try{
|
||||
runningLock.wait() ;
|
||||
}
|
||||
catch (InterruptedException ie)
|
||||
{}
|
||||
}
|
||||
if ( !stillRunning )
|
||||
break ;
|
||||
}
|
||||
|
||||
read = in.read ( data );
|
||||
|
||||
if ( read == -1 )
|
||||
{
|
||||
_log.debug ( "Handler " + id + ": connection closed" );
|
||||
break;
|
||||
}
|
||||
|
||||
totalReceived += read ;
|
||||
|
||||
recv.receiveStreamBytes ( id, data, read );
|
||||
}
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
_log.debug ( "Caught IOException", e );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
i2pSocket.close();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
_log.debug ( "Caught IOException", e );
|
||||
}
|
||||
|
||||
if ( stillRunning )
|
||||
{
|
||||
removeSocketHandler ( id );
|
||||
// FIXME: we need error reporting here!
|
||||
|
||||
try
|
||||
{
|
||||
recv.notifyStreamDisconnection ( id, "OK", null );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
_log.debug ( "Error sending disconnection notice for handler "
|
||||
+ id, e );
|
||||
}
|
||||
}
|
||||
|
||||
_log.debug ( "Shutting down SAM STREAM session socket handler " + id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Revision: 1.1 $
|
||||
* $Revision: 1.2 $
|
||||
*/
|
||||
|
||||
package i2p.susi.dns;
|
||||
@ -76,6 +76,8 @@ public class AddressbookBean
|
||||
deletionMarks = new LinkedList();
|
||||
}
|
||||
private long configLastLoaded = 0;
|
||||
private static final String PRIVATE_BOOK = "private_addressbook";
|
||||
private static final String DEFAULT_PRIVATE_BOOK = "../privatehosts.txt";
|
||||
private void loadConfig()
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
@ -86,6 +88,9 @@ public class AddressbookBean
|
||||
try {
|
||||
properties.clear();
|
||||
properties.load( new FileInputStream( ConfigBean.configFileName ) );
|
||||
// added in 0.5, for compatibility with 0.4 config.txt
|
||||
if( properties.getProperty(PRIVATE_BOOK) == null)
|
||||
properties.setProperty(PRIVATE_BOOK, DEFAULT_PRIVATE_BOOK);
|
||||
configLastLoaded = currentTime;
|
||||
}
|
||||
catch (Exception e) {
|
||||
@ -112,8 +117,9 @@ public class AddressbookBean
|
||||
public String getBook()
|
||||
{
|
||||
if( book == null || ( book.compareToIgnoreCase( "master" ) != 0 &&
|
||||
book.compareToIgnoreCase( "router" ) != 0 ) &&
|
||||
book.compareToIgnoreCase( "published" ) != 0 )
|
||||
book.compareToIgnoreCase( "router" ) != 0 &&
|
||||
book.compareToIgnoreCase( "private" ) != 0 &&
|
||||
book.compareToIgnoreCase( "published" ) != 0 ))
|
||||
book = "master";
|
||||
|
||||
return book;
|
||||
@ -163,7 +169,11 @@ public class AddressbookBean
|
||||
list.addLast( new AddressBean( name, destination ) );
|
||||
}
|
||||
// Format a message about filtered addressbook size, and the number of displayed entries
|
||||
message = "Filtered list contains " + list.size() + " entries";
|
||||
if( filter != null && filter.length() > 0 )
|
||||
message = "Filtered l";
|
||||
else
|
||||
message = "L";
|
||||
message += "ist contains " + list.size() + " entries";
|
||||
if (list.size() > 300) message += ", displaying the first 300."; else message += ".";
|
||||
|
||||
Object array[] = list.toArray();
|
||||
@ -251,6 +261,10 @@ public class AddressbookBean
|
||||
{
|
||||
return getBook().compareToIgnoreCase( "published" ) == 0;
|
||||
}
|
||||
public boolean isPrivate()
|
||||
{
|
||||
return getBook().compareToIgnoreCase( "private" ) == 0;
|
||||
}
|
||||
public void setFilter(String filter) {
|
||||
if( filter != null && ( filter.length() == 0 || filter.compareToIgnoreCase( "none" ) == 0 ) ) {
|
||||
filter = null;
|
||||
|
@ -19,14 +19,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Revision: 1.4 $
|
||||
* $Revision: 1.1 $
|
||||
*/
|
||||
|
||||
package i2p.susi.dns;
|
||||
|
||||
public class VersionBean {
|
||||
|
||||
private static String version = "0.4";
|
||||
private static String version = "0.5";
|
||||
private static String url = "http://susi.i2p/?i2paddresshelper=T2DU1KAz3meB0B53U8Y06-I7vHR7XmC0qXAJfLW6b-1L1FVKoySRZz4xazHAwyv2xtRpvKrv6ukLm1tThEW0zQWtZPtX8G6KkzMibD8t7IS~4yw-9VkBtUydyYfsX08AK3v~-egSW8HCXTdyIJVtrETJb337VDUHW-7D4L1JLbwSH4if2ooks6yFTrljK5aVMi-16dZOVvmoyJc3jBqSdK6kraO4gW5-vHTmbLwL498p9nug1KOg1DqgN2GeU5X1QlVrlpFb~IIfdP~O8NT7u-LAjW3jSJsMbLDHMSYTIhC7xmJIiBoi-qk8p6TLynAmvJ7HRvbx4N1EB-uJHyD16wsZkkHyEOfmXbj0ZqLyKEGb3thPwCz-M9v~c2Qt3WbwjXJAtHpjlHkdJ4Fg91cX2oak~JoapnPf6Syw8hko5syf6VVoCYLnrrYyM8oGl8mLclHkj~VCidQNqMSM74IhrHfK6HmRikqtZBexb5M6wfMTTqBvaHURdD21GOpFKYBUAAAA";
|
||||
|
||||
public String getVersion() {
|
||||
|
@ -20,7 +20,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Revision: 1.2 $
|
||||
* $Revision: 1.3 $
|
||||
*/
|
||||
%>
|
||||
<%@ page contentType="text/html"%>
|
||||
@ -48,9 +48,11 @@
|
||||
<p>addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> *
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
<a href="config.jsp">configuration</a>
|
||||
<a href="config.jsp">configuration</a> *
|
||||
<a href="index.jsp">overview</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -92,7 +94,8 @@
|
||||
<a href="addressbook.jsp?filter=0-9">0-9</a>
|
||||
<a href="addressbook.jsp?filter=none">all</a></p>
|
||||
<c:if test="${book.hasFilter}">
|
||||
<p>Current filter: ${book.filter}</p>
|
||||
<p>Current filter: ${book.filter}
|
||||
(<a href="addressbook.jsp?filter=none">clear filter</a>)</p>
|
||||
</c:if>
|
||||
</div>
|
||||
|
||||
@ -117,7 +120,7 @@
|
||||
<table class="book" cellspacing="0" cellpadding="5">
|
||||
<tr class="head">
|
||||
|
||||
<c:if test="${book.master || book.router || book.published}">
|
||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
||||
<th> </th>
|
||||
</c:if>
|
||||
|
||||
@ -127,7 +130,7 @@
|
||||
<!-- limit iterator to 300, or "Form too large" may result on submit -->
|
||||
<c:forEach items="${book.entries}" var="addr" begin="0" end="299">
|
||||
<tr class="list${book.trClass}">
|
||||
<c:if test="${book.master || book.router || book.published}">
|
||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
||||
<td class="checkbox"><input type="checkbox" name="checked" value="${addr.name}" alt="Mark for deletion"></td>
|
||||
</c:if>
|
||||
<td class="names"><a href="http://${addr.name}/">${addr.name}</a> -
|
||||
@ -139,7 +142,7 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<c:if test="${book.master || book.router || book.published}">
|
||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
||||
<div id="buttons">
|
||||
<p class="buttons"><input type="image" name="action" value="delete" src="images/delete.png" alt="Delete checked" />
|
||||
</p>
|
||||
|
@ -20,7 +20,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Revision: 1.14 $
|
||||
* $Revision: 1.1 $
|
||||
*/
|
||||
%>
|
||||
<%@ page contentType="text/html" %>
|
||||
@ -43,9 +43,11 @@
|
||||
addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> *
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
<a href="config.jsp">configuration</a>
|
||||
configuration *
|
||||
<a href="index.jsp">overview</a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="headline">
|
||||
@ -65,22 +67,22 @@ addressbooks
|
||||
<div id="help">
|
||||
<h3>Hints</h3>
|
||||
<ol>
|
||||
<li>All file or directory paths here are relative to the addressbooks working directory, which normally
|
||||
<li>All file or directory paths here are relative to the addressbook's working directory, which normally
|
||||
is located at $I2P/addressbook/.</li>
|
||||
<li>If you want to manually add lines to an addressbook, add them to the master addressbook. The router
|
||||
<li>If you want to manually add lines to an addressbook, add them to the private or master addressbooks. The router
|
||||
addressbook and the published addressbook are overwritten by the addressbook application.</li>
|
||||
<li><b>Important:</b>When you publish your addressbook, <b>ALL</b> destinations appear there, even those
|
||||
from your master addressbook. Unfortunately the master addressbook points to your userhosts.txt, which was
|
||||
used for private destinations before. So if you want to keep the destinations in your userhosts.txt secret,
|
||||
please change the master addressbook to a different file before turning on addressbook publishing.</li>
|
||||
<li><b>Important:</b>When you publish your addressbook, <b>ALL</b> destinations from the master and router addressbooks appear there.
|
||||
Use the private addressbook for private destinations, these are not published.
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Options</h3>
|
||||
<ul>
|
||||
<li><b>subscriptions</b> - file containing the list of subscriptions URLs (no need to change)</li>
|
||||
<li><b>update_delay</b> - update interval in hours (no need to change)</li>
|
||||
<li><b>published_addressbook</b> - your public hosts.txt file (choose a path within your webserver document root)</li>
|
||||
<li><b>router_addressbook</b> - your hosts.txt (no need to change)</li>
|
||||
<li><b>master_addressbook</b> - your personal addressbook, it gets never overwritten by the addressbook</li>
|
||||
<li><b>router_addressbook</b> - your hosts.txt (don't change)</li>
|
||||
<li><b>master_addressbook</b> - your personal addressbook, it never gets overwritten by the addressbook (don't change)</li>
|
||||
<li><b>private_addressbook</b> - your private addressbook, it is never published (defaults to ../privatehosts.txt, don't change)</li>
|
||||
<li><b>proxy_port</b> - http port for your eepProxy (no need to change)</li>
|
||||
<li><b>proxy_host</b> - hostname for your eepProxy (no need to change)</li>
|
||||
<li><b>should_publish</b> - true/false whether to write the published addressbook</li>
|
||||
@ -93,4 +95,4 @@ please change the master addressbook to a different file before turning on addre
|
||||
<p class="footer">susidns v${version.version} © <a href="${version.url}">susi</a> 2005 </p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -20,7 +20,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Revision: 1.1 $
|
||||
* $Revision: 1.2 $
|
||||
*/
|
||||
%>
|
||||
<%@ page contentType="text/html"%>
|
||||
@ -42,9 +42,11 @@
|
||||
<p>addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> *
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
<a href="config.jsp">configuration</a>
|
||||
<a href="config.jsp">configuration</a> *
|
||||
overview
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -52,23 +54,25 @@
|
||||
<h3>Huh? what addressbook?</h3>
|
||||
<p>
|
||||
The addressbook application is part of your i2p installation. It regularly updates your hosts.txt file
|
||||
from distributed sources. It keeps your hosts.txt up to date, so it automatically contains all new
|
||||
eepsites announced on <a href="http://orion.i2p">orion</a>
|
||||
or in the <a href="http://forum.i2p/viewforum.php?f=16">forum</a>.
|
||||
from distributed sources. It keeps your hosts.txt up to date, so it can automatically add
|
||||
eepsites announced on other sites if you subscribe to those sites' addressbooks.
|
||||
</p>
|
||||
<p>
|
||||
(To speak the truth: In its default configuration the addressbook does not poll
|
||||
orion, but dev.i2p only. Subscribing to <a href="http://orion.i2p">orion</a> is an easy task,
|
||||
just add <a href="http://orion.i2p/hosts.txt">http://orion.i2p/hosts.txt</a> to your <a href="subscriptions.jsp">subscriptions</a> file.)
|
||||
additional sites, but www.i2p2.i2p only. Subscribing to additional sites is an easy task,
|
||||
just add them to your <a href="subscriptions.jsp">subscriptions</a> file.)
|
||||
</p>
|
||||
<p>If you have questions about naming in i2p, there is an excellent <a href="http://forum.i2p.net/viewtopic.php?t=134">introduction</a>
|
||||
from duck in the forum.</p>
|
||||
<h3>How does the addressbook work?</h3>
|
||||
<p>The addressbook application regularly (normally once per hour) polls your subscriptions and merges their content
|
||||
into your so called router addressbook (normally your plain hosts.txt). Then it merges your so called master addressbook (normally
|
||||
your userhosts.txt) into the router addressbook as well. If configured the router addressbook is now written to the so published addressbook,
|
||||
which is a publicly available copy of your hosts.txt somewhere in your eepsites document root. (Yes, this means that, with activated publication,
|
||||
your once private keys from userhosts.txt now are publicly available for everybody.)
|
||||
into your so-called router addressbook (normally your plain hosts.txt). Then it merges your so-called master addressbook (normally
|
||||
your userhosts.txt) into the router addressbook as well. If configured, the router addressbook is now written to the published addressbook,
|
||||
which is a publicly available copy of your hosts.txt somewhere in your eepsite's document root.
|
||||
</p><p>
|
||||
The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published.
|
||||
Hosts in the private addressbook can be accessed by you but their addresses are never distributed to others.
|
||||
The private addressbook can also be used for aliases of hosts in your other addressbooks.
|
||||
</p>
|
||||
<p><img src="images/how.png" border="0" alt="addressbook working scheme"/></p>
|
||||
</div>
|
||||
|
@ -20,7 +20,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Revision: 1.7 $
|
||||
* $Revision: 1.2 $
|
||||
*/
|
||||
%>
|
||||
<%@ page contentType="text/html"%>
|
||||
@ -42,9 +42,11 @@
|
||||
<p>addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
<a href="config.jsp">configuration</a>
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
subscriptions *
|
||||
<a href="config.jsp">configuration</a> *
|
||||
<a href="index.jsp">overview</a>
|
||||
</p>
|
||||
</div>
|
||||
<div id="headline">
|
||||
@ -66,9 +68,8 @@
|
||||
<p class="help">
|
||||
The subscription file contains a list of (i2p) URLs. The addressbook application
|
||||
regularly (once per hour) checks this list for new eepsites. Those URLs simply contain the published hosts.txt
|
||||
file of other people. Default subscription is the hosts.txt from dev.i2p. The most
|
||||
popular collaboration site for eepsite is orion.i2p. So its a good idea to add http://orion.i2p/hosts.txt
|
||||
as a 2nd subscription.
|
||||
file of other people. The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently.
|
||||
So it is a good idea to add additional subscriptions to sites that have the latest addresses.
|
||||
</p>
|
||||
</div>
|
||||
<div id="footer">
|
||||
|
@ -138,6 +138,9 @@
|
||||
<pathelement location="apps/i2ptunnel/java/src" />
|
||||
<pathelement location="apps/systray/java/src" />
|
||||
<pathelement location="apps/routerconsole/java/src" />
|
||||
<pathelement location="apps/addressbook/java/src" />
|
||||
<pathelement location="apps/i2psnark/java/src" />
|
||||
<pathelement location="apps/sam/java/src" />
|
||||
</sourcepath>
|
||||
<classpath>
|
||||
<pathelement location="apps/jetty/jettylib/org.mortbay.jetty.jar" />
|
||||
|
52
checklist.txt
Normal file
52
checklist.txt
Normal file
@ -0,0 +1,52 @@
|
||||
Release checklist
|
||||
-----------------
|
||||
|
||||
Sync with mtn.i2p2.i2p
|
||||
Start with a clean checkout mtn -d i2p.mtn co --branch=i2p.i2p
|
||||
|
||||
Change revision in:
|
||||
history.txt
|
||||
initialNews.xml
|
||||
installer/install.xml
|
||||
news.xml
|
||||
router/java/src/net/i2p/router/RouterVersion.java
|
||||
|
||||
Build and tag:
|
||||
ant dist
|
||||
mtn ci
|
||||
mtn tag i2p-0.6.1.xx
|
||||
Sync with mtn.i2p2.i2p
|
||||
|
||||
Create a signed update file with:
|
||||
export I2P=~/i2p
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate sign i2pupdate.zip i2pupdate.sud /path/to/private.key 0.6.1.xx
|
||||
|
||||
Verify signed update file with:
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate showversion i2pupdate.sud
|
||||
java -cp $I2P/lib/i2p.jar net.i2p.crypto.TrustedUpdate verifysig i2pupdate.sud
|
||||
|
||||
Make the source tarball:
|
||||
Start with a clean checkout mtn -d i2p.mtn co --branch=i2p.i2p i2p-0.6.1.xx
|
||||
tar tjf i2p-0.6.1.xx.tar.bz2 --exclude i2p-0.6.1.xx/_MTN i2p-0.6.1.xx
|
||||
mv i2p-0.6.1.xx.tar.bz2 i2p.i2p
|
||||
|
||||
More signatures:
|
||||
sha1sum i2pinstall.exe i2p.tar.bz2 i2p-0.6.1.xx.tar.bz2 i2pupdate.zip
|
||||
gpg -b i2pinstall.exe
|
||||
gpg -b i2p.tar.bz2
|
||||
gpg -b i2p-0.6.1.xx.tar.bz2
|
||||
gpg -b i2pupdate.zip
|
||||
|
||||
Distribute files to download locations and to www.i2p2.i2p
|
||||
|
||||
Website files to change:
|
||||
Sync with mtn.i2p2.i2p
|
||||
announcements.html
|
||||
download.html (change SHA1s)
|
||||
index.html
|
||||
hosts.txt (copy from mtn)
|
||||
Sync with mtn.i2p2.i2p
|
||||
|
||||
Copy news.xml to subscription location
|
||||
|
||||
Announce on #i2p, forum.i2p, Syndie
|
@ -60,6 +60,45 @@ jP69nPbh4KLGhF+SD0+0bW4=
|
||||
=npPe
|
||||
-----END PGP SIGNATURE-----
|
||||
*/
|
||||
/*
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
*/
|
||||
/* zzz's key */
|
||||
private static final String DEFAULT_TRUSTED_KEY2 =
|
||||
"lT54eq3SH0TWWwQ1wgH6XPelIno7wH7UfiZOpQg-ZuxdNhc4UjjrohKdK" +
|
||||
"Zqfswt1ANPnmOlMewLGBESl7kJB9c5sByz~IOlNyz5BMLRC~R~ZC9QI4W" +
|
||||
"XwUBYW8BhYO2mkvtdOrcy690lDkwzdf5xLxlCBpQlTaLYzQVjVWBcvbCA=";
|
||||
/*
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFHdupcQVV2uqduC+0RAocuAKCR4ILLuz3RB8QT7zkadmS2LmFuMwCgweqG
|
||||
lFm5Fqx/iW5+k0QaQZ3W9mY=
|
||||
=V3i7
|
||||
-----END PGP SIGNATURE-----
|
||||
*/
|
||||
/*
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
*/
|
||||
/* Complication's key */
|
||||
private static final String DEFAULT_TRUSTED_KEY3 =
|
||||
"JHFA0yXUgKtmhajXFZH9Nk62OPRHbvvQHTi8EANV-D~3tjLjaz9p9cs6F" +
|
||||
"s8W3FSLfUwsQeFg7dfVSQQZga~1jMjboo94vIcm3j6XbW4mbcorVQ74uP" +
|
||||
"jd8EA1AQhJ6bBTxDAFk~6fVDOdhHT0Wo5CcUn7v8bAYY3x3UWiL8Remx0=";
|
||||
/*
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFHphOV+h38a3n8zjMRAll+AJ9KA6WiDJcTN4qfrslSemUMr+FBrwCeM8pF
|
||||
D8usM7Dxp5yrDrCYZ5AIijc=
|
||||
=SrXI
|
||||
-----END PGP SIGNATURE-----
|
||||
*/
|
||||
|
||||
private static final String VALID_VERSION_CHARS = "0123456789.";
|
||||
private static final int VERSION_BYTES = 16;
|
||||
private static final int HEADER_BYTES = Signature.SIGNATURE_BYTES + VERSION_BYTES;
|
||||
@ -92,14 +131,18 @@ jP69nPbh4KLGhF+SD0+0bW4=
|
||||
String propertyTrustedKeys = context.getProperty(PROP_TRUSTED_KEYS);
|
||||
|
||||
if ( (propertyTrustedKeys != null) && (propertyTrustedKeys.length() > 0) ) {
|
||||
StringTokenizer propertyTrustedKeysTokens = new StringTokenizer(propertyTrustedKeys, ",");
|
||||
StringTokenizer propertyTrustedKeysTokens = new StringTokenizer(propertyTrustedKeys, " ,\r\n");
|
||||
|
||||
while (propertyTrustedKeysTokens.hasMoreTokens())
|
||||
_trustedKeys.add(propertyTrustedKeysTokens.nextToken().trim());
|
||||
|
||||
} else {
|
||||
_trustedKeys.add(DEFAULT_TRUSTED_KEY);
|
||||
_trustedKeys.add(DEFAULT_TRUSTED_KEY2);
|
||||
_trustedKeys.add(DEFAULT_TRUSTED_KEY3);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("TrustedUpdate created, trusting " + _trustedKeys.size() + " keys.");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,6 +223,7 @@ jP69nPbh4KLGhF+SD0+0bW4=
|
||||
private static final void genKeysCLI(String publicKeyFile, String privateKeyFile) {
|
||||
FileOutputStream fileOutputStream = null;
|
||||
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
try {
|
||||
Object signingKeypair[] = _context.keyGenerator().generateSigningKeypair();
|
||||
SigningPublicKey signingPublicKey = (SigningPublicKey) signingKeypair[0];
|
||||
@ -273,7 +317,26 @@ jP69nPbh4KLGhF+SD0+0bW4=
|
||||
public ArrayList getTrustedKeys() {
|
||||
return _trustedKeys;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the trusted keys for the current instance.
|
||||
*
|
||||
* @return A <code>String</code> containing the trusted keys,
|
||||
* delimited by CR LF line breaks.
|
||||
*/
|
||||
public String getTrustedKeysString() {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
for (int i = 0; i < _trustedKeys.size(); i++) {
|
||||
// If something already buffered, first add line break.
|
||||
if (buf.length() > 0) buf.append("\r\n");
|
||||
buf.append((String) _trustedKeys.get(i));
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads the version string from a signed update file.
|
||||
*
|
||||
|
@ -236,6 +236,10 @@ public class DataHelper {
|
||||
if (split <= 0) continue;
|
||||
String key = line.substring(0, split);
|
||||
String val = line.substring(split+1);
|
||||
// Unescape line breaks after loading.
|
||||
// Remember: "\" needs escaping both for regex and string.
|
||||
val = val.replaceAll("\\\\r","\r");
|
||||
val = val.replaceAll("\\\\n","\n");
|
||||
if ( (key.length() > 0) && (val.length() > 0) )
|
||||
if (forceLowerCase)
|
||||
props.setProperty(key.toLowerCase(), val);
|
||||
|
@ -392,6 +392,8 @@ public class EepGet {
|
||||
timeout.cancel();
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).attemptFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt, _numRetries, ioe);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("ERR: doFetch failed " + ioe);
|
||||
} finally {
|
||||
if (_out != null) {
|
||||
try {
|
||||
@ -418,6 +420,8 @@ public class EepGet {
|
||||
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).transferFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("All attempts failed for " + _url);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -478,7 +482,7 @@ public class EepGet {
|
||||
boolean strictSize = (_bytesRemaining >= 0);
|
||||
|
||||
// If minimum or maximum size defined, ensure they aren't exceeded
|
||||
if ((_minSize > -1) && (_bytesRemaining < _minSize))
|
||||
if ((_minSize > 0) && (_bytesRemaining < _minSize))
|
||||
throw new IOException("HTTP response size " + _bytesRemaining + " violates minimum of " + _minSize + " bytes");
|
||||
if ((_maxSize > -1) && (_bytesRemaining > _maxSize))
|
||||
throw new IOException("HTTP response size " + _bytesRemaining + " violates maximum of " + _maxSize + " bytes");
|
||||
@ -500,6 +504,8 @@ public class EepGet {
|
||||
// Hopefully this won't break compatibility with existing status listeners
|
||||
// (cause them to behave weird, or show weird numbers).
|
||||
_alreadyTransferred += read;
|
||||
if ((_maxSize > -1) && (_alreadyTransferred > _maxSize)) // could transfer a little over maxSize
|
||||
throw new IOException("Bytes transferred " + _alreadyTransferred + " violates maximum of " + _maxSize + " bytes");
|
||||
remaining -= read;
|
||||
if (remaining==0 && _encodingChunked) {
|
||||
int char1 = _proxyIn.read();
|
||||
@ -544,10 +550,13 @@ public class EepGet {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Done transferring " + _bytesTransferred + " (ok? " + !_transferFailed + ")");
|
||||
|
||||
|
||||
if (_transferFailed) {
|
||||
// 404, etc
|
||||
// 404, etc - transferFailed is called after all attempts fail, by fetch() above
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).transferFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt);
|
||||
((StatusListener)_listeners.get(i)).attemptFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt, _numRetries, new Exception("Attempt failed"));
|
||||
} else if ((_minSize > 0) && (_alreadyTransferred < _minSize)) {
|
||||
throw new IOException("Bytes transferred " + _alreadyTransferred + " violates minimum of " + _minSize + " bytes");
|
||||
} else if ( (_bytesRemaining == -1) || (remaining == 0) ) {
|
||||
for (int i = 0; i < _listeners.size(); i++)
|
||||
((StatusListener)_listeners.get(i)).transferComplete(
|
||||
@ -615,6 +624,11 @@ public class EepGet {
|
||||
rcOk = false;
|
||||
_transferFailed = true;
|
||||
}
|
||||
|
||||
// clear out the arguments, as we use the same variables for return values
|
||||
_etag = null;
|
||||
_lastModified = null;
|
||||
|
||||
buf.setLength(0);
|
||||
byte lookahead[] = new byte[3];
|
||||
while (true) {
|
||||
|
151
history.txt
151
history.txt
@ -1,4 +1,153 @@
|
||||
$Id: history.txt,v 1.592 2007-10-07 21:36:17 complication Exp $
|
||||
* 2008-02-10 0.6.1.31 released
|
||||
|
||||
2008-02-10 Complication
|
||||
* Update news and version numbers
|
||||
|
||||
2008-02-06 zzz
|
||||
* build.xml: Add some apps to javadoc
|
||||
* checklist.txt: Add some things
|
||||
* news.xml: make links relative
|
||||
* runplain.sh: Add some comments
|
||||
* wrapper.config: Add some comments
|
||||
|
||||
2008-02-05 Complication
|
||||
* Change the dates too (sorry for such forgetfulness!)
|
||||
|
||||
2008-02-04 Complication
|
||||
* Also use the new key for checking, and add it into news.xml
|
||||
|
||||
2008-02-04 Complication
|
||||
* Added my release signing key into TrustedUpdate.java
|
||||
|
||||
2008-01-31 zzz
|
||||
* NewsFetcher: Change fetch failed from error to warning
|
||||
* installer: Fix URL and "email"
|
||||
* checklist.txt: New release checklist
|
||||
|
||||
2008-01-29 zzz
|
||||
* Addressbook: Change default subscription
|
||||
* ConfigUpdateHandler: Change default news URL
|
||||
* initialNews.xml: Update version to .31
|
||||
* news.xml: More updates
|
||||
* hosts.txt: Add i2p-projekt.i2p
|
||||
* readme.html: More URL updates
|
||||
* SusiDNS: Change references to default subscription
|
||||
|
||||
2008-01-28 zzz
|
||||
* news.xml: Updates, still preliminary
|
||||
* ReseedHandler: Change default URL
|
||||
* i2ptunnel.config: Change default outproxies
|
||||
* readme.html: Change *.i2p.net URLs
|
||||
* help.jsp: Change *.i2p.net URLs
|
||||
* eepsite_index.html: Change stats.i2p addressbook subscription URL
|
||||
* hosts.txt: Add krabs.i2p, true.i2p, www.i2p2.i2p
|
||||
|
||||
* 2008-01-28 0.6.1.30-20 converted from CVS to MTN
|
||||
|
||||
2008-01-08 zzz
|
||||
* addressbook: Limit size of subscribed hosts.txt,
|
||||
don't save old etag or last-modified data
|
||||
* EepGet: Add some logging,
|
||||
enforce size limits even when size not in returned header,
|
||||
don't return old etag or last-modified data,
|
||||
don't call transferFailed listener more than once
|
||||
* Sign my update signing key
|
||||
* NewsFetcher: add last-modified support, reduce number of retries
|
||||
* Error pages: add icon and logo,
|
||||
clarify 'destination not found' and 'proxy not found' pages
|
||||
|
||||
2008-01-07 zzz
|
||||
* profiles.jsp formatting cleanup
|
||||
* NTCP: Reduce max idle time from 60m to 20m
|
||||
* NTCP: Fix idle time on connections with zero messages,
|
||||
correctly drop these connections
|
||||
|
||||
2008-01-03 zzz
|
||||
* addressbook: Do basic validation of hostnames and destkeys
|
||||
* susidns: Add support for the private addressbook,
|
||||
update the text and links somewhat
|
||||
|
||||
2008-01-02 zzz
|
||||
* Add stats.i2p to the jump list
|
||||
* Impose 20MB limit on POSTs and catch OOMs in POST
|
||||
* eepsite_index.html: add stats.i2p services
|
||||
* addressbook: log source of new keys; disallow dests > 516 bytes
|
||||
* addressbook: convert hostnames to lower case to prevent duplicates
|
||||
* susidns: generalize references to orion
|
||||
|
||||
2007-12-29 zzz
|
||||
* Tweak IRC inbound PONG filtering to fix xchat/BitchX lagometers
|
||||
* Allow commas in router.trustedUpdateKeys and router.updateURL again
|
||||
* Change default news host from dev.i2p.net to dev.i2p
|
||||
* Change jetty timeout from 30 to 60 sec (thanks sponge!)
|
||||
|
||||
2007-12-28 zzz
|
||||
* Add zzz's update signing key
|
||||
|
||||
2007-12-26 Complication
|
||||
* Improve reseed handler (less repetitive code,
|
||||
avoid reporting errors when less than 10% of fetches fail)
|
||||
|
||||
2007-12-26 Complication
|
||||
* Escape both CR, LF and CR LF line breaks in Router.saveConfig()
|
||||
and unescape them in DataHelper.loadProps() to support
|
||||
saving and loading config properties with line breaks
|
||||
* Change the update URLs textbox into a textarea like keys have,
|
||||
so different URLs go on different lines
|
||||
* Modify TrustedUpdate to provide a method which supplies a key list
|
||||
delimited with CR LF line breaks
|
||||
* Modify DEFAULT_UPDATE_URL to supply a default URL list
|
||||
delimited with CR LF line breaks
|
||||
* Modify selectUpdateURL() to handle URL lists
|
||||
delimited by any kind of line breaks
|
||||
* Start saving trusted update keys
|
||||
* Improve formatting on configupdate.jsp
|
||||
|
||||
2007-12-22 zzz
|
||||
* Add support for multiple update URLs
|
||||
* Change default for update to use i2p proxy,
|
||||
add several URLs as defaults
|
||||
* Enable trusted key form on configupdate.jsp
|
||||
* Clarify the 'destination not found' error page
|
||||
|
||||
2007-12-16 zzz
|
||||
* i2psnark: remove anonymitytracker from default list
|
||||
|
||||
2007-12-10 zzz
|
||||
* Fix NPE in CLI TrustedUpdate keygen
|
||||
|
||||
2007-12-02 Complication
|
||||
* Commit SAM v2 patch from mkvore (thank you!)
|
||||
* Minor reformatting to preserve consistent whitespace
|
||||
in old SAM classes (new classes unaltered)
|
||||
|
||||
2007-12-01 Complication
|
||||
* Separate the checks "does Jetty .zip file need downloading"
|
||||
and "does Jetty .zip file need extracting" in the Jetty buildfile.
|
||||
First download (unless already done), then extract (unless done).
|
||||
|
||||
2007-11-26 zzz
|
||||
* i2psnark: add timeout for receive inactivity
|
||||
|
||||
2007-11-24 zzz
|
||||
* i2psnark: increase streaming lib write timeout to 240 sec and change
|
||||
timeout action from "ping" to "disconect", as the fix in .30 to
|
||||
honor options on outbound connections led to hung outbound connections
|
||||
(bitfield never transmitted, connection never dropped)
|
||||
|
||||
2007-11-06 jrandom
|
||||
* add i2host.i2p to the jump list
|
||||
|
||||
2007-10-11 zzz
|
||||
* IRC Proxy: Fix several possible anonymity holes:
|
||||
- Block CTCP in NOTICE messages
|
||||
- Block CTCP anywhere in PRIVMSG and NOTICE, not just at first character
|
||||
- Check for lower case commands
|
||||
(Thanks sponge!)
|
||||
|
||||
2007-10-07 jrandom
|
||||
* back out the NTCP backlog pushback, as it could be used to mount an
|
||||
active anonymity attack.
|
||||
|
||||
* 2007-10-07 0.6.1.30 released
|
||||
|
||||
|
216
hosts.txt
216
hosts.txt
@ -1,213 +1,3 @@
|
||||
; TC's hosts.txt guaranteed freshness
|
||||
; $Id: hosts.txt,v 1.170 2007-02-12 05:26:21 jrandom Exp $
|
||||
; changelog:
|
||||
; (1.192) added trevorreznik.i2p
|
||||
; (1.191) added trac.i2p
|
||||
; (1.190) added archive.syndie.i2p
|
||||
; (1.189) added mtn.i2p
|
||||
; (1.188) added downloads.legion.i2p, politguy.i2p, ninja.i2p
|
||||
; (1.187) added hidden.i2p, bk1k.i2p, antipiracyagency.i2p
|
||||
; (1.186) added decadence.i2p, freedomarchives.i2p, closedshop.i2p
|
||||
; (1.185) added TheBreton.i2p adab.i2p awup.i2p china.i2p davidkra.i2p
|
||||
; comwiz.i2p dust.i2p eepsites.i2p jmg.i2p kuroneko.i2p
|
||||
; mywastedlife.i2p site.games.i2p squid2.i2p striker.i2p
|
||||
; tracker.awup.i2p zzz.i2p
|
||||
; (1.184) added sion.i2p, betaguru.i2p jnymo.i2p always.i2p gonzo2000.i2p
|
||||
; flipkick.i2p mindisl0st.i2p torapa.i2p wahoo.i2p badfish.i2p
|
||||
; slack.i2p bobcat.i2p pycache.awup.i2p lp.i2p amazone.i2p
|
||||
; inproxy.tino.i2p kohaar.i2p
|
||||
; (1.183) added ttc.i2p
|
||||
; (1.182) added tracker-fr.i2p
|
||||
; (1.181) added syncline.i2p, cerebrum.i2p, news.underscore.i2p,
|
||||
; onionforum.i2p, frostmirror.i2p, ptm.i2p, gloinsblog.i2p
|
||||
; underscore.i2p, mac7.i2p, wiht.i2p, jazzy.i2p, trwcln.i2p
|
||||
; (1.180) added tino.i2p and fproxy.tino.i2p
|
||||
; (1.179) added glog.i2p
|
||||
; (1.178) added syndie.i2p and syndiemedia.i2p
|
||||
; (1.177) added irc.freshcoffee.i2p
|
||||
; (1.176) added surrender.adab.i2p
|
||||
; (1.175) added terror.i2p
|
||||
; (1.174) added irc.arcturus.i2p
|
||||
; (1.173) added tracker.postman.i2p, hq.postman.i2p
|
||||
; (1.172) added i2p-bt.postman.i2p
|
||||
; (1.171) added luckypunk.i2p
|
||||
; (1.170) added bash.i2p, stats.i2p
|
||||
; (1.169) added archive.i2p, www.fr.i2p, romster.i2p, marshmallow.i2p, openforums.i2p
|
||||
; (1.168) removed duplicate manveru.i2p
|
||||
; (1.167) added bittorrent.i2p
|
||||
; (1.166) added elf.i2p, de-ebooks.i2p, i2pchan.i2p, longhorn.i2p
|
||||
; (1.165) added amobius.i2p
|
||||
; (1.164) added google.i2p
|
||||
; (1.163) added mrplod.i2p
|
||||
; (1.162) added sirup.i2p
|
||||
; (1.161) added connelly.i2p
|
||||
; (1.160) added wspucktracker.i2p
|
||||
; (1.159) added 55cancri.i2p
|
||||
; (1.158) added tracker.fr.i2p
|
||||
; (1.157) added v2mail.i2p, complication.i2p
|
||||
; (1.156) added lazyguy.i2p
|
||||
; (1.155) added confessions.i2p, rsync.thetower.i2p, redzara.i2p, gaytorrents.i2p
|
||||
; (1.154) added arkan.i2p, search.i2p, floureszination.i2p, antipiratbyran.i2p
|
||||
; asylum.i2p, templar.i2p
|
||||
; (1.153) added feedspace.i2p
|
||||
; (1.152) added wiki.fr.i2p
|
||||
; (1.151) added septu.i2p
|
||||
; (1.150) added music.i2p, rotten.i2p, wintermute.i2p, kaji2.i2p, aspnet.i2p,
|
||||
; gaming.i2p, nntp.i2p
|
||||
; (1.149) added cowsay.i2p
|
||||
; (1.148) added irc.postman.i2p
|
||||
; (1.147) added subrosa.i2p
|
||||
; (1.146) added moxonom.i2p
|
||||
; (1.145) added sex0r.i2p flock.i2p cneal.i2p www.nntp.i2p wallsgetbombed.i2p
|
||||
; thedarkside.i2p legion.i2p manveru.i2p books.manveru.i2p bt.i2p
|
||||
; (1.144) added riaa.i2p
|
||||
; (1.143) added mpaa.i2p
|
||||
; (1.142) added pants.i2p
|
||||
; (1.141) added irc.carambar.i2p
|
||||
; (1.140) added general.i2p
|
||||
; (1.139) added smeghead.i2p
|
||||
; (1.138) added nntp.fr.i2p
|
||||
; (1.137) added deadgod.i2p
|
||||
; (1.136) added manveru.i2p
|
||||
; (1.135) added fr.i2p
|
||||
; (1.134) added imhotep.i2p
|
||||
; (1.133) added jrandom.dev.i2p (ed. note: yes, i am me)
|
||||
; (1.132) added ttp.i2p
|
||||
; (1.131) added freenet.eco.i2p, tracker.i2p, photo.i2p
|
||||
; (1.130) added hopekiller.i2p, microsoft.i2p, jhor.i2p, badtoys.i2p
|
||||
; (1.129) added mindspore.i2p
|
||||
; (1.128) added irc.ircbnc.i2p
|
||||
; (1.127) added dvdr-core.i2p
|
||||
; (1.126) added j.i2p
|
||||
; (1.125) added bl.i2p
|
||||
; (1.124) removed jap.eco.i2p and bt1.eco.i2p (obsolete)
|
||||
; (1.123) added chat.i2p
|
||||
; (1.122) added phonebooth.i2p
|
||||
; (1.121) added up.i2p
|
||||
; (1.120) added dm.i2p
|
||||
; (1.119) added piespy.i2p
|
||||
; (1.118) added sciencebooks.i2p
|
||||
; (1.117) added forum.fr.i2p, fedo.i2p, and pastebin.i2p
|
||||
; (1.116) added frosk.i2p
|
||||
; (1.115) added theland.i2p
|
||||
; (1.114) added dox.i2p
|
||||
; (1.113) added amiga.i2p
|
||||
; (1.112) added frooze.i2p
|
||||
; (1.111) aliased gott.i2p as jrandom.i2p (ed. note: no, i am not gott)
|
||||
; (1.110) added sonax.i2p
|
||||
; (1.109) added 1.fcp.freenet.i2p and copied fcp.i2p to 2.fcp.freenet.i2p
|
||||
; (1.108) added asciiwhite.i2p
|
||||
; (1.107) added fcp.i2p
|
||||
; (1.106) added greenflog.i2p
|
||||
; (1.105) added bdl.i2p
|
||||
; (1.104) added bacardi.i2p and guttersnipe.i2p
|
||||
; (1.103) added evil.i2p
|
||||
; (1.102) added bsdm.i2p
|
||||
; (1.101) added eschaton.i2p
|
||||
; (1.100) added blog.curiosity.i2p
|
||||
; (1.99) added slacker.i2p
|
||||
; (1.98) added ses.i2p and pdforge.i2p
|
||||
; (1.97) added orion.i2p and protokol.i2p
|
||||
; (1.96) added blog.polecat.i2p
|
||||
; (1.95) added ciaran.i2p
|
||||
; (1.94) added polecat.i2p
|
||||
; (1.93) added susi.i2p
|
||||
; (1.92) removed duplicate beyond.i2p, added edge.i2p
|
||||
; (1.91) added shiftfox.i2p
|
||||
; (1.90) added underground.i2p
|
||||
; (1.89) renamed newsbytetest.i2p to newsbyte.i2p
|
||||
; (1.88) added newsbytetest.i2p
|
||||
; (1.87) updated curiosity.i2p (via signed email)
|
||||
; (1.86) added blueheron.i2p
|
||||
; (1.85) updated files.i2p (after verifying ident)
|
||||
; (1.84) added utansans.i2p
|
||||
; (1.83) added irc.orz.i2p
|
||||
; (1.82) added nano.i2p
|
||||
; (1.81) added ragnarok.i2p
|
||||
; (1.80) added marcos.i2p
|
||||
; (1.79) updated beyond.i2p's key
|
||||
; (1.78) added b.i2p
|
||||
; (1.77) added tinyurl.i2p
|
||||
; (1.76) added detonate.i2p
|
||||
; (1.75) added identiguy.i2p
|
||||
; (1.74) added jabber-2.i2p
|
||||
; (1.73) added jake.i2p
|
||||
; (1.72) added anonymnet.i2p sasquotch.i2p orz.i2p microbleu.i2p {www,smtp,pop3}.postman.i2p
|
||||
; (1.71) added curiosity.i2p
|
||||
; (1.70) added freeciv.nightblade.i2p
|
||||
; (1.69) added xolotl.i2p
|
||||
; (1.68) added modulus.i2p
|
||||
; (1.67) added eepdot.i2p
|
||||
; (1.66) removed datagram_test.i2p
|
||||
; (1.65) added socks1.tor.i2p
|
||||
; (1.64) added sugadude.i2p
|
||||
; (1.63) added files.i2p
|
||||
; (1.62) added beyond.i2p
|
||||
; (1.61) added gott.i2p
|
||||
; (1.60) added linuxagent.i2p
|
||||
; (1.59) added www.i2p, dev.i2p, and cvs.i2p, removed i2pcvs.i2p
|
||||
; (1.58) updated lucky.i2p (after not checking ID, but, c'mon...)
|
||||
; (1.57) added firerabbit.i2p
|
||||
; (1.56) added datagram_test.i2p
|
||||
; (1.55) updated ardvark.i2p (after checking ID)
|
||||
; (1.54) added files.nickster.i2p
|
||||
; (1.53) added brittanyworld.i2p
|
||||
; (1.52) added stasher.i2p
|
||||
; (1.51) changed quadn.i2p to library.i2p
|
||||
; (1.50) added freshcoffee.i2p
|
||||
; (1.49) added ems.i2p
|
||||
; (1.48) added ooo.i2p
|
||||
; (1.47) added fproxy2.i2p
|
||||
; (1.46) removed hypercubus.i2p
|
||||
; (1.45) added thetower.i2p
|
||||
; (1.44) added fproxy.i2p and mrflibble.i2p
|
||||
; (1.43) added files.hypercubus.i2p
|
||||
; (1.42) added www1.squid.i2p
|
||||
; (1.41) added quadn.i2p
|
||||
; (1.40) added nickster2.i2p and irc.nickster.i2p (pointing at IIP)
|
||||
; (1.39) added jdot.i2p
|
||||
; (1.38) added forum.i2p
|
||||
; (1.36) added ferret.i2p
|
||||
; (1.36) added anonynanny.i2p
|
||||
; (1.35) added hypercubus.i2p
|
||||
; (1.34) added ogg.baffled.i2p
|
||||
; (1.33) added morph.i2p
|
||||
; (1.32) added nickster.i2p
|
||||
; (1.31) added mush.zeit.i2p (i2p's first eepMUSH)
|
||||
; (1.30) added xilog.i2p
|
||||
; (1.29) added lucky.i2p, removed lp.i2p
|
||||
; (1.28) added sungo.i2p
|
||||
; (1.27) added jar.i2p
|
||||
; (1.26) added tor-www-proxy.i2p (WWW through tor by human - won't be up 24/7!)
|
||||
; (1.25) added ugha.i2p
|
||||
; (1.24) added reefer.i2p
|
||||
; (1.23) added nic.i2p
|
||||
; (1.22) added www.janonymous.i2p
|
||||
; (1.21) added bluebeam.i2p
|
||||
; (1.20) added echo.baffled.i2p (which runs mihi's echo server - telnet and get replies)
|
||||
; (1.19) added irc.baffled.i2p (which is hooked up with irc.duck.i2p over i2p)
|
||||
; (1.18) added www.aum.i2p, nntp.baffled.i2p, www.baffled.i2p, and ardvark.i2p
|
||||
; (1.17) added gernika's eepsite
|
||||
; (1.16) added duck's scp and hosting server
|
||||
; (1.15) added eco's beta i2psnark server
|
||||
; (1.14) added duck's pgp keyserver
|
||||
; (1.13) added human's eepsite, the mail servers, and luckypunk's eepsite
|
||||
; (1.12) added fillament's chessd server (FICS based clients or telnet to it)
|
||||
; (1.11) added mp3.tc.i2p and mesh.firerabbit.i2p
|
||||
; (1.10) added aum's mp3 and ogg streams
|
||||
; (1.9) added the FCP and HTTP keys for a private entropy node, as well as nm's eepsite
|
||||
; (1.8) updated nightblade's eepsite (after confirming ident w/ trent on iip)
|
||||
; (1.7) added aum's eepsite
|
||||
; (1.6) added fillament's flog/plog and eco's eepsite
|
||||
; (1.5) added duck's irc
|
||||
; (1.4) added eco's JAP tunnel
|
||||
; (1.3) added duck's eepsite
|
||||
; (1.2) fixed duck's subdomain names
|
||||
; (1.1) added nntp, jabber, squid, and i2pcvs (and imported into i2p's cvs for distribution)
|
||||
; (1.0) added dyad.i2p and nightblade.i2p
|
||||
; (0.5) added bozo.i2p
|
||||
; (0.0) added tc.i2p
|
||||
;
|
||||
tc.i2p=3RPLOkQGlq8anNyNWhjbMyHxpAvUyUJKbiUejI80DnPR59T3blc7-XrBhQ2iPbf-BRAR~v1j34Kpba1eDyhPk2gevsE6ULO1irarJ3~C9WcQH2wAbNiVwfWqbh6onQ~YmkSpGNwGHD6ytwbvTyXeBJcS8e6gmfNN-sYLn1aQu8UqWB3D6BmTfLtyS3eqWVk66Nrzmwy8E1Hvq5z~1lukYb~cyiDO1oZHAOLyUQtd9eN16yJY~2SRG8LiscpPMl9nSJUr6fmXMUubW-M7QGFH82Om-735PJUk6WMy1Hi9Vgh4Pxhdl7gfqGRWioFABdhcypb7p1Ca77p73uabLDFK-SjIYmdj7TwSdbNa6PCmzEvCEW~IZeZmnZC5B6pK30AdmD9vc641wUGce9xTJVfNRupf5L7pSsVIISix6FkKQk-FTW2RsZKLbuMCYMaPzLEx5gzODEqtI6Jf2teMd5xCz51RPayDJl~lJ-W0IWYfosnjM~KxYaqc4agviBuF5ZWeAAAA
|
||||
dyad.i2p=W~JFpqSH8uopylox2V5hMbpcHSsb-dJkSKvdJ1vj~KQcUFJWXFyfbetBAukcGH5S559aK9oslU0qbVoMDlJITVC4OXfXSnVbJBP1IhsK8SvjSYicjmIi2fA~k4HvSh9Wxu~bg8yo~jgfHA8tjYppK9QKc56BpkJb~hx0nNGy4Ny9eW~6A5AwAmHvwdt5NqcREYRMjRd63dMGm8BcEe-6FbOyMo3dnIFcETWAe8TCeoMxm~S1n~6Jlinw3ETxv-L6lQkhFFWnC5zyzQ~4JhVxxT3taTMYXg8td4CBGmrS078jcjW63rlSiQgZBlYfN3iEYmurhuIEV9NXRcmnMrBOQUAoXPpVuRIxJbaQNDL71FO2iv424n4YjKs84suAho34GGQKq7WoL5V5KQgihfcl0f~xne-qP3FtpoPFeyA9x-sA2JWDAsxoZlfvgkiP5eyOn23prT9TJK47HCVilHSV11uTVaC4Jc5YsjoBCZadWbgQnMCKlZ4jk-bLE1PSWLg7AAAA
|
||||
nightblade.i2p=nyErwSseXbsojcWtNkDyUul0YULtqr6qyWSzIp639Ygpe8juCdgPMLURVXcmlCvo~QPoHg6zt53KpgpGvB1-Wv2SGvc2Mvs~o8USw3ius8fP1URphqcBbulK8Ci0bgknt0kD0AfxqfMz-p~xk1QEMxq2kZEoB3oyIIFnQlpb2ByS74Lx8iKzXTrwWk19I3Dvu4nIq8CBDDwu3lYoCD2kC-jT5pjgglverGPEGN4o55LYVTtfSg4gAJFZeaE4KjBR5P1z7cca6UDjGMWfR0iCa8P3qpkY2ODYpk~8w2xgBbgDq-8Hzik~uraHc598ccS8QpwB0f0Jw~2PZcTjOPdZ-239U6p3tESXa7FXzRBCujv4Bx6CVFRhCmBHpyFnCD-MugZ~vR6XFSS2XBsCT~duXKq94HH2n1iAWslG4Vu44ut1JVhDPFzp~Dk7wujB0tCo2HXH2icRQxOWe37foU4LZSJ4oMpFDACBzwSfcZdIPsVRxGttKQx4yzgffR1Q~Jl7AAAA
|
||||
@ -506,4 +296,8 @@ mtn.i2p=RqXC4xbFK6t3g2wk9SO4RjY7mj1c0DmtMra5c1Md8t-DcNPSjQFmqT97pcZ5IR1JDKqyCO7R
|
||||
archive.syndie.i2p=iXX0DadZTJQpPr1to0OmQ4xokHgx1HYd5ec7~zIjQ80W~p4kRCYJmEzibH2Kn59Gi04SAXeA2O9i3bNqfGCQjsbz7UcjPGrW6-UrckXVXW67Moxp7QWY6i-aKuVYM3bqYxUL2mWvcDzJ8D0ecMpvasxhxwXpdFn2J6CGboMxeGV8R3hwwlNYbYoKgHr74qEJaIZpm1FrRWvNHV5cMv363iWnPy72XspQefk79-VOjPsxfummosU7gqlxl5teyiGKNzMs3G6iJyfVHO8IlKtdn~P~ET9p7zWlTPgV8NTyCVB-Wn5S3JMkMGOFZR7wSlxSwGFpTFQKc7mxVTtLZ5nWcV2OhvOIxRZ31RvGJZyVs562RC5aMfyqcM5IHQiZVlmkhzJKIy9VDw8tKayQtRM-xeN5k6Qr7iMmYIRORwuAODkYApoMD9a0eJ6ZYOSgBMOCSvYcwfT8axRY~GabiHm0QC82mo-nDgrUypGKtOPMI9MIqMTsb8Yl-UGWn6twBAIzAAAA
|
||||
trac.i2p=OBnF9NtkEsPij2F-lp3bWDVrJsPQQPdq6adlpq0N4BY1XRjtDBZl~EpDdk7roq49~ptKAQG2cNUeBEKIIrdlZhJio5pMwUl6YinizzkNTFfZipB5OKoB7PBulxkw-N9mKMhS1btd9ajcV8tiP3xiv7VSlgiDwbdKg1fmkvNrVrJnzkN3-ey2kebYnbh7jjU2gPFUl~CwSEkIi6AK9EfqmFR-DUVohyygqAY~fi4EMeTVXGUqftXSNFYUwpRJgFrWRPTurtZnJK5403q67oEk0eWrPIZ8ytJWSBfffAXL3ts~0O1FZeKXUccsAl33j70~lklSolNVLJ40y-6X5ZLWajmX0ONU3j0qI5A~7fgNgsg-vKypPDuzl8ug-D~BmhqdAf0sRYmziDVwTgU~WRB6IzhhXFR6CbwrGXdgOGg2qNT1eOnMwGo3SMMJ7kK88VC5LdYg2dyiyjZATuvT92QdZglrVQIeBqAehcFjOBuycC1ED3AOak8D9Xplj7V6hN-HAAAA
|
||||
trevorreznik.i2p=FxoG5dx6WuF8gu0Fc4ItB61hd8dBZ0L6FjkvoA-kQrC0DcY5YUqKBUmrcxzKhKo4nLyg0jRV-RSNUuWsali44dmpHQ6wuFjCGTr5zMk0NoVUpBsBNtHLEQWxROnuQFlQAq6x~eVdU5bAvnNFd-6RXDJ86Br9bf5YG4PHmZPon7ld3t1kAvPaZepITKlIq5iXy3va-pzAMFEIhDtLMzFjGhLWMg9m-8tkx4577WvzUWbSAUdxKkxwjecIzbTDTQsZld~t5MkaMmn5UpNX6Gh3iDUPWHXOjn4I8MIELiSaeRdpHDgua3mo~p8oO0QvWBgn~jQ8yr6nz7vMAdoRtOwPlUqHCCM1BsPVcN9a92rPpTFBk0BXikjJJrkDDIaFjJnKmRAsEUoa-eHaPV~RS0QPrfuzlp0XjBzQcAQjNIw6hO4xqJujSs8SdObMpQAqCR5Sc5NzOvTr5eAzCIz0gmQnKrA1RJVOebKDERM~qQ6rFrdVDkjLEJd6SyjUr-TdIrayAAAA
|
||||
|
||||
i2host.i2p=FkX89~FOWc2HjTeVerud7hzZCtQNDKqEvMeJiDEnSzneA44hhDEDSbjiDuEWOCPwvgCwrzMg9o3apHXosNMnRVTYlYIJWb1~fgRnzkHIJnz2yrojLcTElTLMgQSzHdV04ock3oPHjw8r2j73hnTiq5u3HhexT0D-IK02S0GUd9cPcP2YnWlNMnGuA-J6s7VHUd5mUhBO3LeOcOusBUOjsbt79bwBZYsnnVV~JRSVzHPd8kYbRMEjDuyaIJHEr2pkwwtrk~BqLeZ5UCbbVob1-733FtOfQXjKTpFPK~IlHDM7ItgXt77U5KZHkZ54WQYJNCE6HlE7LhFB79cqjgvxXTfvyjoqZVJ1lq1yFS8GtLcnurJLkN5BleCEDJEK3D7kCymCpngW9wlKjakEc85ZculU65neqIpqIk6noir6e1vseeUZKxBM3k6AYkLoFYSh98PpENjTHUdaNTl1kQA2Mmi9zobGS0gn0~RWHFord19TC5ReBtOFWkseksHp-5-nAAAA
|
||||
true.i2p=Jeb1Ctlh55wWezbA~sCxYQsreDPS~qFJ6DeNMPl7~Kx0w1Odh8YE3QKrZS7WlNqeoRNJLyPgf7h19Tosb-ATZOPDH7B4pQvI4CdlTv-Uimq4dI71PRRZQr3mCBihW~WtVReDOO3JiDf1Bx225xhTmWp0KYo5AM91EW0TcHi8immHBFB9jcjekPoU~zlVAqy5S07LnS7f7rWtC7kno983Dyi9arWDPmnnzu2QD4mMrH0EkuuoBqwUi1HBUNhTn~lL8KqfSpg9j9q-eqd~eixF3nOlsrxMFuWVV1HOUtyMUTRGEX4i4IDPWmRQeFZ0gmfeBYdad~nG1X7uBVeeEtGSrggnegXoSE4oaIuONNXYORsevZn8UahC~kkNWg1wPQtr57TirhLirkF2qHUuwAqe5G00PIhC0-J8K5Ye0QDd5a1coQT87kBgcqLcbSR1oGIjxv2Ma6970Fv65a2a~YKqZZbuGof5-5-7X48SVhOigmo2c-COyt2rXoQlGQpBWtDsAAAA
|
||||
krabs.i2p=k6qIwzff6s1RiRQQy9O6cliBTfHffKZ2F~pVG8nmCqMxEpPnywynFa9XVS6VBbhxGRAMG~PIb2IaFRYS5GFdM3fnnJ~Cn2AbN-qsqbl6cXExj5Fy9Cd-aPR44XW0NE9qjFPiN~6JUOg0fitF65RmsMrFvHq9LM2zOFxOfnPKVsBJGRpjhp6EPRNrkXvzQTw7x6~kqUJ-VGW0avjrz4EmgT6Wias5z0EPioneKOhG-1NepL8HqEv9ryGt31~kmI1-B0cS8v1riaXH0rZWjJ0VvUFEoJ3sHCir4vsnSf1YQIKMUO~zKlgTVZBsw8P2ILFFihs0g9KMIWVjJqqo0PzCM1O-LW90hirn~Ryh4zOZI-orIiV9Oqu96Fj2bvBYSka11TY7erLOCk64tc5NwxvlJQ3F-lk0ZFGvYuU~l45mi0khFLnDnzhDFtcY6YNLRG8hmv9IR2MrG9TJFfSwXdx11LI-57tkRi9Jw4s8OjLijNNDOJX~rVgwZVVIEQcOhGxkAAAA
|
||||
www.i2p2.i2p=-KR6qyfPWXoN~F3UzzYSMIsaRy4udcRkHu2Dx9syXSzUQXQdi2Af1TV2UMH3PpPuNu-GwrqihwmLSkPFg4fv4yQQY3E10VeQVuI67dn5vlan3NGMsjqxoXTSHHt7C3nX3szXK90JSoO~tRMDl1xyqtKm94-RpIyNcLXofd0H6b02683CQIjb-7JiCpDD0zharm6SU54rhdisIUVXpi1xYgg2pKVpssL~KCp7RAGzpt2rSgz~RHFsecqGBeFwJdiko-6CYW~tcBcigM8ea57LK7JjCFVhOoYTqgk95AG04-hfehnmBtuAFHWklFyFh88x6mS9sbVPvi-am4La0G0jvUJw9a3wQ67jMr6KWQ~w~bFe~FDqoZqVXl8t88qHPIvXelvWw2Y8EMSF5PJhWw~AZfoWOA5VQVYvcmGzZIEKtFGE7bgQf3rFtJ2FAtig9XXBsoLisHbJgeVb29Ew5E7bkwxvEe9NYkIqvrKvUAt1i55we0Nkt6xlEdhBqg6xXOyIAAAA
|
||||
i2p-projekt.i2p=8ZAW~KzGFMUEj0pdchy6GQOOZbuzbqpWtiApEj8LHy2~O~58XKxRrA43cA23a9oDpNZDqWhRWEtehSnX5NoCwJcXWWdO1ksKEUim6cQLP-VpQyuZTIIqwSADwgoe6ikxZG0NGvy5FijgxF4EW9zg39nhUNKRejYNHhOBZKIX38qYyXoB8XCVJybKg89aMMPsCT884F0CLBKbHeYhpYGmhE4YW~aV21c5pebivvxeJPWuTBAOmYxAIgJE3fFU-fucQn9YyGUFa8F3t-0Vco-9qVNSEWfgrdXOdKT6orr3sfssiKo3ybRWdTpxycZ6wB4qHWgTSU5A-gOA3ACTCMZBsASN3W5cz6GRZCspQ0HNu~R~nJ8V06Mmw~iVYOu5lDvipmG6-dJky6XRxCedczxMM1GWFoieQ8Ysfuxq-j8keEtaYmyUQme6TcviCEvQsxyVirr~dTC-F8aZ~y2AlG5IJz5KD02nO6TRkI2fgjHhv9OZ9nskh-I2jxAzFP6Is1kyAAAA
|
||||
|
@ -1,5 +1,5 @@
|
||||
<i2p.news date="$Date: 2007-08-23 19:33:29 $">
|
||||
<i2p.release version="0.6.1.30" date="2007/02/15" minVersion="0.6"
|
||||
<i2p.news date="$Date: 2008-02-10 15:00:00 $">
|
||||
<i2p.release version="0.6.1.31" date="2008/02/10" minVersion="0.6"
|
||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
|
||||
publicurl="http://dev.i2p.net/i2p/i2pupdate.sud"
|
||||
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-September/000878.html"
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
<info>
|
||||
<appname>i2p</appname>
|
||||
<appversion>0.6.1.30</appversion>
|
||||
<appversion>0.6.1.31</appversion>
|
||||
<authors>
|
||||
<author name="I2P" email="support@i2p.net"/>
|
||||
<author name="I2P" email="http://forum.i2p.net"/>
|
||||
</authors>
|
||||
<url>http://www.i2p.net</url>
|
||||
<url>http://www.i2p2.de</url>
|
||||
</info>
|
||||
|
||||
<guiprefs width="590" height="356" resizable="yes">
|
||||
|
0
installer/lib/launch4j/bin/ld
Normal file → Executable file
0
installer/lib/launch4j/bin/ld
Normal file → Executable file
0
installer/lib/launch4j/bin/ld.exe
Normal file → Executable file
0
installer/lib/launch4j/bin/ld.exe
Normal file → Executable file
0
installer/lib/launch4j/bin/windres
Normal file → Executable file
0
installer/lib/launch4j/bin/windres
Normal file → Executable file
0
installer/lib/launch4j/bin/windres.exe
Normal file → Executable file
0
installer/lib/launch4j/bin/windres.exe
Normal file → Executable file
@ -6,6 +6,7 @@ Proxy-Connection: close
|
||||
|
||||
<html><head>
|
||||
<title>Destination key conflict</title>
|
||||
<link rel="shortcut icon" href="http://localhost:7657/favicon.ico" />
|
||||
<style type='text/css'>
|
||||
div.warning {
|
||||
margin: 0em 1em 1em 224px;
|
||||
@ -31,7 +32,7 @@ div.logo {
|
||||
</head>
|
||||
<body>
|
||||
<div class=logo>
|
||||
<a href="http://localhost:7657/index.jsp">Router Console</a><br />
|
||||
<a href="http://localhost:7657/index.jsp" title="Router Console"><img src="http://localhost:7657/i2plogo.png" alt="Router Console" width="187" height="35" border="0"/></a><br />
|
||||
[<a href="http://localhost:7657/config.jsp">configuration</a> | <a href="http://localhost:7657/help.jsp">help</a>]
|
||||
</div>
|
||||
<div class=warning id=warning>
|
||||
|
@ -6,6 +6,7 @@ Proxy-Connection: close
|
||||
|
||||
<html><head>
|
||||
<title>Eepsite not reachable</title>
|
||||
<link rel="shortcut icon" href="http://localhost:7657/favicon.ico" />
|
||||
<style type='text/css'>
|
||||
div.warning {
|
||||
margin: 0em 1em 1em 224px;
|
||||
@ -31,13 +32,13 @@ div.logo {
|
||||
</head>
|
||||
<body>
|
||||
<div class=logo>
|
||||
<a href="http://localhost:7657/index.jsp">Router Console</a><br />
|
||||
<a href="http://localhost:7657/index.jsp" title="Router Console"><img src="http://localhost:7657/i2plogo.png" alt="Router Console" width="187" height="35" border="0"/></a><br />
|
||||
[<a href="http://localhost:7657/config.jsp">configuration</a> | <a href="http://localhost:7657/help.jsp">help</a>]
|
||||
</div>
|
||||
<div class=warning id=warning>
|
||||
The eepsite was not reachable. Perhaps
|
||||
the link you are following is
|
||||
bad. The eepsite could also
|
||||
be temporarily offline. You may want to
|
||||
The eepsite was not reachable.
|
||||
The eepsite is temporarily offline, there is network congestion,
|
||||
or your router is not yet well-integrated with peers.
|
||||
You may want to
|
||||
<a href="javascript: window.location.reload()">retry</a>.
|
||||
<BR><BR>Could not find the following destination:<BR><BR>
|
||||
|
@ -6,6 +6,7 @@ Proxy-Connection: close
|
||||
|
||||
<html><head>
|
||||
<title>Invalid eepsite destination</title>
|
||||
<link rel="shortcut icon" href="http://localhost:7657/favicon.ico" />
|
||||
<style type='text/css'>
|
||||
div.warning {
|
||||
margin: 0em 1em 1em 224px;
|
||||
@ -31,7 +32,7 @@ div.logo {
|
||||
</head>
|
||||
<body>
|
||||
<div class=logo>
|
||||
<a href="http://localhost:7657/index.jsp">Router Console</a><br />
|
||||
<a href="http://localhost:7657/index.jsp" title="Router Console"><img src="http://localhost:7657/i2plogo.png" alt="Router Console" width="187" height="35" border="0"/></a><br />
|
||||
[<a href="http://localhost:7657/config.jsp">configuration</a> | <a href="http://localhost:7657/help.jsp">help</a>]
|
||||
</div>
|
||||
<div class=warning id=warning>
|
||||
|
@ -6,6 +6,7 @@ Proxy-Connection: close
|
||||
|
||||
<html><head>
|
||||
<title>Eepsite unknown</title>
|
||||
<link rel="shortcut icon" href="http://localhost:7657/favicon.ico" />
|
||||
<style type='text/css'>
|
||||
div.warning {
|
||||
margin: 0em 1em 1em 224px;
|
||||
@ -31,14 +32,13 @@ div.logo {
|
||||
</head>
|
||||
<body>
|
||||
<div class=logo>
|
||||
<a href="http://localhost:7657/index.jsp">Router Console</a><br />
|
||||
<a href="http://localhost:7657/index.jsp" title="Router Console"><img src="http://localhost:7657/i2plogo.png" alt="Router Console" width="187" height="35" border="0"/></a><br />
|
||||
[<a href="http://localhost:7657/config.jsp">configuration</a> | <a href="http://localhost:7657/help.jsp">help</a>]
|
||||
</div>
|
||||
<div class=warning id=warning>
|
||||
The eepsite was not found in your router's addressbook.
|
||||
Check the link or find a BASE64 address.
|
||||
If you have the BASE64 address, paste it into your userhosts.txt using SusiDNS
|
||||
<a href="http://localhost:7657/susidns/addressbook.jsp?book=master">here</a>.
|
||||
or use a BASE64 address helper.
|
||||
You may be able to find the eepsite's address helper at <a href="http://orion.i2p">orion.i2p</a>.
|
||||
If you have the BASE64 address, paste it into your userhosts.txt using
|
||||
<a href="http://localhost:7657/susidns/addressbook.jsp?book=master">SusiDNS</a>,
|
||||
use a BASE64 address helper, or use a jump service link below.
|
||||
<BR><BR>Could not find the following destination:<BR><BR>
|
||||
|
@ -6,6 +6,7 @@ Proxy-Connection: close
|
||||
|
||||
<html><head>
|
||||
<title>Outproxy Not Found</title>
|
||||
<link rel="shortcut icon" href="http://localhost:7657/favicon.ico" />
|
||||
<style type='text/css'>
|
||||
div.warning {
|
||||
margin: 0em 1em 1em 224px;
|
||||
@ -32,13 +33,14 @@ div.logo {
|
||||
</head>
|
||||
<body>
|
||||
<div class=logo>
|
||||
<a href="http://localhost:7657/index.jsp">Router Console</a><br />
|
||||
<a href="http://localhost:7657/index.jsp" title="Router Console"><img src="http://localhost:7657/i2plogo.png" alt="Router Console" width="187" height="35" border="0"/></a><br />
|
||||
[<a href="http://localhost:7657/config.jsp">configuration</a> | <a href="http://localhost:7657/help.jsp">help</a>]
|
||||
</div>
|
||||
<div class=warning id=warning>
|
||||
The WWW Outproxy was not found.
|
||||
It could
|
||||
be temporarily offline. You may want to
|
||||
It is offline, there is network congestion,
|
||||
or your router is not yet well-integrated with peers.
|
||||
You may want to
|
||||
<a href="javascript: parent.window.location.reload()">retry</a>
|
||||
as this will randomly reselect an outproxy from the pool you have defined
|
||||
<a href="http://localhost:7657/i2ptunnel/index.jsp">here</a>
|
||||
|
@ -14,16 +14,15 @@
|
||||
<a href="http://localhost:7657/i2ptunnel/edit.jsp?tunnel=3">configuration page</a>).
|
||||
The instructions below detail how to assign a name like "mysite.i2p" to your key and
|
||||
start up your eepsite.</p>
|
||||
<p>You can also reach your eepsite locally through
|
||||
<a href="http://localhost:7658/">http://localhost:7658/</a>. If you
|
||||
want to change the port number, edit the file ./eepsite/jetty.xml and
|
||||
update the I2PTunnel configuration accordingly.</p>
|
||||
<p>You can reach your eepsite locally through
|
||||
<a href="http://localhost:7658/">http://localhost:7658/</a>.
|
||||
</p>
|
||||
|
||||
<h2>Step-by-step instructions for starting your new eepsite and announcing it to the I2P community</h2>
|
||||
Your eepsite is stopped by default.
|
||||
After you start it, it will be difficult for other people to find because it
|
||||
doesn't have a name and they don't have your really long Base64 key.
|
||||
You could just tell people that really long key but thankfully i2p has an address book
|
||||
You could just tell people that really long key, but thankfully i2p has an address book
|
||||
and several easy ways to tell people about your eepsite. Here's detailed instructions.
|
||||
<ul>
|
||||
<li>Pick a name for your eepsite (<i>something</i>.i2p). Use all lower-case.
|
||||
@ -52,44 +51,47 @@
|
||||
<li>Before you tell the world about your new eepsite, you should add some content.
|
||||
Go to i2p/eepsite/docroot and copy this document (index.html) to help.html so you can refer to it later.
|
||||
Now edit index.html and add content, pictures, and whatever you would like to share.
|
||||
<li>Now it's time to add your eepsite to an I2P address book
|
||||
such as <a href="http://orion.i2p/">orion.i2p</a> or
|
||||
<a href="http://trevorreznik.i2p/">trevorreznik.i2p</a>.
|
||||
<li>Now it's time to add your eepsite to an I2P address book hosted by a site
|
||||
such as <a href="http://stats.i2p/">stats.i2p</a>.
|
||||
That is, you must enter
|
||||
your eepsite name and key into a web interface on one or more of these sites.
|
||||
Here is <a href="http://orion.i2p/list/">the key entry form at orion.i2p</a> and
|
||||
Here is <a href="http://stats.i2p/i2p/addkey.html">the key entry form at stats.i2p</a>,
|
||||
here is <a href="http://orion.i2p/list/">the key entry form at orion.i2p</a> and
|
||||
here is <a href="http://trevorreznik.i2p/host-database/">the key entry form at trevorreznik.i2p</a>.
|
||||
Again, your key is the entire "Local destination" key on the
|
||||
<a href="http://localhost:7657/i2ptunnel/edit.jsp?tunnel=3">eepsite i2ptunnel configuration page</a>.
|
||||
Be sure you get the whole thing, ending with "AAAA".
|
||||
Don't forget to click "add a key".
|
||||
Check to see if it reports the key was added.
|
||||
Since many routers periodically get address book updates from orion or trevorreznik, within several hours others will be able to find your
|
||||
Since many routers periodically get address book updates from these sites, within several hours others will be able to find your
|
||||
website by simply typing <i>something</i>.i2p into their browser.
|
||||
<li>Speaking of address book updates, this would be a good time to add orion, trevorreznik, or both
|
||||
<li>Speaking of address book updates, this would be a good time to add some more addressbooks
|
||||
to your own subscription list. Go to your <a href="http://localhost:7657/susidns/subscriptions.jsp">subscriptions configuration page</a>
|
||||
and add <a href="http://orion.i2p/hosts.txt">http://orion.i2p/hosts.txt</a> and/or
|
||||
<a href="http://trevorreznik.i2p/hosts.txt">http://trevorreznik.i2p/hosts.txt</a> to the list and hit "Save".
|
||||
and add a couple of these -
|
||||
<a href="http://orion.i2p/hosts.txt">http://orion.i2p/hosts.txt</a>,
|
||||
<a href="http://tino.i2p/hosts.txt">http://tino.i2p/hosts.txt</a>,
|
||||
<a href="http://stats.i2p/cgi-bin/newhosts.txt">http://stats.i2p/cgi-bin/newhosts.txt</a>,
|
||||
<a href="http://trevorreznik.i2p/hosts.txt">http://trevorreznik.i2p/hosts.txt</a> and hit "Save".
|
||||
Now you will get updates too!
|
||||
<li>If you are in a hurry and can't wait a few hours, you can tell people to use a "jump" address helper redirection service.
|
||||
This will work within a few minutes of your entering the key to an address book.
|
||||
Test it yourself first by entering http://orion.i2p/jump/<i>something</i>.i2p
|
||||
or http://trevorreznik.i2p/cgi-bin/jump.php?hostname=<i>something</i>.i2p/ into your browser.
|
||||
or http://stats.i2p/cgi-bin/jump.cgi?a=<i>something</i>.i2p or
|
||||
or http://trevorreznik.i2p/cgi-bin/jump.php?hostname=<i>something</i>.i2p into your browser.
|
||||
Once it's working, then you can tell others to use it.
|
||||
<li>Some people check <a href="http://orion.i2p/list/">orion.i2p/list/</a> and
|
||||
<li>Some people check eepsite lists such as
|
||||
<a href="http://inproxy.tino.i2p/status.php">inproxy.tino.i2p/status.php</a> for new eepsites, so you may start getting
|
||||
a few visitors. But there are plenty of other ways to tell people. Here are a few ideas:
|
||||
<ul>
|
||||
<li>Post a message on the <a href="http://forum.i2p/viewforum.php?f=16">Eepsite announce forum</a>
|
||||
on <a href="http://forum.i2p/">forum.i2p</a>.
|
||||
<li>Tell people about it on the #i2p or #i2p-chat channels on IRC.
|
||||
<li>Put it in a new post on <a href="syndie.i2p.net">the new Syndie</a>.
|
||||
<li>Put it in a new post on <a href="http://syndie.i2p.net">the new Syndie</a>.
|
||||
<li>Put it in <a href="http://ugha.i2p/EepsiteIndex">Ugha's Eepsite Index Wiki</a>
|
||||
</ul>
|
||||
Note that some sites recommend pasting in that really long destination key.
|
||||
You can if you want - but
|
||||
if you have successfully posted your key at <a href="http://orion.i2p/list/">orion</a> or
|
||||
<a href="http://trevorreznik.i2p/host-database/">trevorreznik</a>,
|
||||
if you have successfully posted your key at an add-key service,
|
||||
tested it using a jump service, and waited 24 hours for the
|
||||
address book update to propagate to others, that shouldn't be necessary.
|
||||
<li>If you have any questions try IRC #i2p or the
|
||||
|
@ -5,7 +5,7 @@ tunnel.0.type=httpclient
|
||||
tunnel.0.sharedClient=true
|
||||
tunnel.0.interface=127.0.0.1
|
||||
tunnel.0.listenPort=4444
|
||||
tunnel.0.proxyList=squid.i2p
|
||||
tunnel.0.proxyList=true.i2p,krabs.i2p
|
||||
tunnel.0.i2cpHost=127.0.0.1
|
||||
tunnel.0.i2cpPort=7654
|
||||
tunnel.0.option.inbound.nickname=shared clients
|
||||
|
@ -25,7 +25,7 @@
|
||||
</Arg>
|
||||
<Set name="MinThreads">3</Set>
|
||||
<Set name="MaxThreads">10</Set>
|
||||
<Set name="MaxIdleTimeMs">30000</Set>
|
||||
<Set name="MaxIdleTimeMs">60000</Set>
|
||||
<Set name="LowResourcePersistTimeMs">1000</Set>
|
||||
<Set name="ConfidentialPort">8443</Set>
|
||||
<Set name="IntegralPort">8443</Set>
|
||||
|
@ -1,3 +1,10 @@
|
||||
#
|
||||
# This runs the router by itself, WITHOUT the wrapper.
|
||||
# This means the router will not restart if it crashes.
|
||||
# Also, you will be using the default memory size, which is
|
||||
# probably not enough for i2p.
|
||||
# You should really use the i2prouter script instead.
|
||||
#
|
||||
export CP=. ; for j in lib/* ; do export CP=$CP:$j ; done;
|
||||
JAVA=java
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
#********************************************************************
|
||||
# Wrapper Properties
|
||||
#
|
||||
# WARNING - for any changes to take effect, you must completely
|
||||
# stop the router and the wrapper. Clicking 'Restart' on your
|
||||
# router console will NOT reread this file! You must
|
||||
# click "Shutdown", wait 11 minutes, then start i2p.
|
||||
#
|
||||
#********************************************************************
|
||||
# Java Application
|
||||
wrapper.java.command=java
|
||||
@ -60,6 +66,13 @@ wrapper.java.additional.4=-Dorg.mortbay.xml.XmlParser.NotValidating=true
|
||||
# The JVM's default is 64MB, and I2P can work fine in that, but to handle
|
||||
# lots of I2PSnark activity in the same JVM, increasing the default max heap
|
||||
# size should help. Feel free to reduce this if not using I2PSnark in the jvm
|
||||
# High-bandwidth routers may need to increase to 256 or more.
|
||||
#
|
||||
# WARNING - for any changes to take effect, you must completely
|
||||
# stop the router and the wrapper. Clicking 'Restart' on your
|
||||
# router console will NOT reread this file! You must
|
||||
# click "Shutdown", wait 11 minutes, then start i2p.
|
||||
#
|
||||
wrapper.java.maxmemory=128
|
||||
|
||||
# Application parameters. Add parameters as needed starting from 1
|
||||
|
108
news.xml
108
news.xml
@ -1,5 +1,5 @@
|
||||
<i2p.news date="$Date: 2007-08-23 21:34:40 $">
|
||||
<i2p.release version="0.6.1.30" date="2007/02/15" minVersion="0.6"
|
||||
<i2p.news date="$Date: 2008-02-10 15:00:00 $">
|
||||
<i2p.release version="0.6.1.31" date="2008/02/10" minVersion="0.6"
|
||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
|
||||
publicurl="http://dev.i2p.net/i2p/i2pupdate.sud"
|
||||
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-September/000878.html"
|
||||
@ -9,18 +9,110 @@
|
||||
publicurl="http://dev.i2p.net/pipermail/i2p/2005-July/000826.html"
|
||||
anonlogs="http://i2p/Nf3ab-ZFkmI-LyMt7GjgT-jfvZ3zKDl0L96pmGQXF1B82W2Bfjf0n7~288vafocjFLnQnVcmZd~-p0-Oolfo9aW2Rm-AhyqxnxyLlPBqGxsJBXjPhm1JBT4Ia8FB-VXt0BuY0fMKdAfWwN61-tj4zIcQWRxv3DFquwEf035K~Ra4SWOqiuJgTRJu7~o~DzHVljVgWIzwf8Z84cz0X33pv-mdG~~y0Bsc2qJVnYwjjR178YMcRSmNE0FVMcs6f17c6zqhMw-11qjKpY~EJfHYCx4lBWF37CD0obbWqTNUIbL~78vxqZRT3dgAgnLixog9nqTO-0Rh~NpVUZnoUi7fNR~awW5U3Cf7rU7nNEKKobLue78hjvRcWn7upHUF45QqTDuaM3yZa7OsjbcH-I909DOub2Q0Dno6vIwuA7yrysccN1sbnkwZbKlf4T6~iDdhaSLJd97QCyPOlbyUfYy9QLNExlRqKgNVJcMJRrIual~Lb1CLbnzt0uvobM57UpqSAAAA/meeting141"
|
||||
publiclogs="http://www.i2p.net/meeting141" />
|
||||
<p>
|
||||
•
|
||||
2007-10-07: 0.6.1.30
|
||||
<a href="http://dev.i2p/pipermail/i2p/2007-October/001356.html">released</a>
|
||||
with
|
||||
sharing by low-bandwidth routers, automatic inbound NTCP addressing,
|
||||
a new reseed handler, and some i2psnark improvements.
|
||||
Delete the old webapps/syndie.war before restarting to save some memory.
|
||||
2008-02-10: <b>0.6.1.31 released</b>
|
||||
</p><p>
|
||||
The transitional 0.6.1.31 release will make the I2P
|
||||
release process independent of jrandom and *.i2p.net servers,
|
||||
introducing two new update verification keys, adding support
|
||||
for distributed update hosting inside I2P, and changing many URLs.
|
||||
</p><p>
|
||||
It introduces version 2 of the SAM protocol,
|
||||
along with substantial improvements to the address book,
|
||||
I2PSnark and ircproxy. Unless you have already done that,
|
||||
read about the update procedure below.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
•
|
||||
2008-02-05: <b>Upcoming 0.6.1.31 Release</b>
|
||||
</p><p>
|
||||
And, since i2p's lead developer
|
||||
<a href="http://dreamtheaterfan.i2p/jrandom-awol.html">has gone AWOL</a>,
|
||||
we do not have his update signing key or write access to
|
||||
<a href="http://www.i2p/">www.i2p</a> or
|
||||
<a href="http://dev.i2p/">dev.i2p</a>.
|
||||
Complication and zzz have generated new signing keys, and they and Amiga are providing
|
||||
update file hosting. These changes must be configured in your router to take effect.
|
||||
</p><p>
|
||||
Make the following configuration changes and your router will automatically install
|
||||
the upcoming 0.6.1.31 release when it becomes available.
|
||||
The release will include SAM v2, new jump server links, and addressbook, IRC proxy, and i2psnark improvements.
|
||||
</p><p>
|
||||
We recommend the automated process as it will verify the key of the signed update file.
|
||||
If you do not make these changes,
|
||||
you will still be able to manually download the new i2pupdate.zip file from locations to
|
||||
be announced.
|
||||
<ol><li>
|
||||
On
|
||||
<a href="configupdate.jsp">configupdate.jsp</a>:
|
||||
</li><ol type="a"><li>
|
||||
Change the News URL to: http://complication.i2p/news.xml
|
||||
</li><li>
|
||||
Select ONE of the following new Update URLs at random and enter it into the Update URL box:
|
||||
<br />http://amiga.i2p/i2p/i2pupdate.sud
|
||||
<br />http://complication.i2p/i2p/i2pupdate.sud
|
||||
<br />http://stats.i2p/i2p/i2pupdate.sud
|
||||
</li><li>
|
||||
Check the box "Update through the eepProxy?"
|
||||
</li><li>
|
||||
Click "Save"
|
||||
</li></ol>
|
||||
<li>
|
||||
On
|
||||
<a href="configadvanced.jsp">configadvanced.jsp</a>:
|
||||
<ol type="a"><li>
|
||||
Add the following line:
|
||||
<br />
|
||||
<textarea rows="1" cols="80" readonly="readonly">router.trustedUpdateKeys=W4kJbnv9KSVwbnapV7SaNW2kMIZKs~hwL0ro9pZXFo1xTwqz45nykCp1HM7sAKYDZay5z1HvYYOl9CNVz00xF03KPU9RUCVxhDZ1YXhZIskPKjUPUsCIpE~Z1C~N9KSEV6~2stDlBNH10VZ4T0X1TrcXwb3IBXliWo2y2GAx~Ow=,lT54eq3SH0TWWwQ1wgH6XPelIno7wH7UfiZOpQg-ZuxdNhc4UjjrohKdKZqfswt1ANPnmOlMewLGBESl7kJB9c5sByz~IOlNyz5BMLRC~R~ZC9QI4WXwUBYW8BhYO2mkvtdOrcy690lDkwzdf5xLxlCBpQlTaLYzQVjVWBcvbCA=,JHFA0yXUgKtmhajXFZH9Nk62OPRHbvvQHTi8EANV-D~3tjLjaz9p9cs6Fs8W3FSLfUwsQeFg7dfVSQQZga~1jMjboo94vIcm3j6XbW4mbcorVQ74uPjd8EA1AQhJ6bBTxDAFk~6fVDOdhHT0Wo5CcUn7v8bAYY3x3UWiL8Remx0=</textarea>
|
||||
</li><li>
|
||||
Click "Apply"
|
||||
</li></ol>
|
||||
<li>
|
||||
You are now ready to automatically receive the 0.6.1.31 update when it becomes available,
|
||||
either by setting your update policy to "download and install" or by clicking on the
|
||||
"update available" link when it appears.
|
||||
</li></li></ol>
|
||||
</p><p>
|
||||
If you would like to verify the trusted update keys, they are also
|
||||
<a href="http://stats.i2p/i2p/signingkeys.html">posted and signed here</a>.
|
||||
</p><p>
|
||||
The new release will be announced here, on
|
||||
<a href="http://forum.i2p/">the forums</a>, on IRC, and on Syndie.
|
||||
New users may install 0.6.1.31 from the
|
||||
<a href="http://www.i2p2.de/download">www.i2p2.de download page</a>.
|
||||
Thank you for your support during this transition. For help please contact us on #i2p.
|
||||
</p><p>
|
||||
Amiga, Complication, welterde, zzz
|
||||
</p>
|
||||
|
||||
<p>
|
||||
•
|
||||
2008-02-05: <b>*.i2p[.net] Replacements</b>
|
||||
<p>
|
||||
As you probably know, <a href="http://www.i2p.net/">www.i2p.net</a>
|
||||
and its related sites and services went down January 13 after
|
||||
a power outage at the hosting facility, and did not return fully to service.
|
||||
While some pages are still available at
|
||||
<a href="http://66.111.51.110/">66.111.51.110</a>
|
||||
we have a new official site at
|
||||
<a href="http://www.i2p2.de/">www.i2p2.de</a>
|
||||
and
|
||||
<a href="http://www.i2p2.i2p/">www.i2p2.i2p</a>.
|
||||
Extensive information about replacements for the various services
|
||||
is available at
|
||||
<a href="http://forum.i2p/viewtopic.php?t=2500">the forums</a>,
|
||||
<a href="http://complication.i2p/">complication.i2p</a>, and
|
||||
<a href="http://zzz.i2p/">zzz.i2p</a>.
|
||||
</p>
|
||||
|
||||
<!--
|
||||
•
|
||||
2007-04-10:
|
||||
<a href="http://dev.i2p/pipermail/i2p/2007-April/001343.html">status notes</a>
|
||||
and
|
||||
<a href="http://www.i2p/meeting206">meeting log</a>
|
||||
<br />
|
||||
-->
|
||||
</i2p.news>
|
||||
|
14
readme.html
14
readme.html
@ -11,14 +11,14 @@ you can:</p>
|
||||
tell your browser to use the <b>HTTP proxy at localhost port 4444</b>, then
|
||||
browse to an eepsite -
|
||||
<ul>
|
||||
<li><a href="http://orion.i2p/">orion.i2p</a>: a site which tracks eepsite uptime and changes</li>
|
||||
<li><a href="http://inproxy.tino.i2p/status.php">inproxy.tino.i2p</a>: a site which tracks active eepsites</li>
|
||||
<li><a href="http://inproxy.tino.i2p/status.php">inproxy.tino.i2p</a> and
|
||||
<a href="http://perv.i2p/stats.cgi">perv.i2p</a>: sites tracking active eepsites</li>
|
||||
<li><a href="http://forum.i2p/">forum.i2p</a>: a secure and anonymous connection to <a href="http://forum.i2p.net/">forum.i2p.net</a></li>
|
||||
<li><a href="http://www.i2p/">www.i2p</a>: a secure and anonymous connection to <a href="http://www.i2p.net/">www.i2p.net</a></li>
|
||||
<li><a href="http://www.i2p2.i2p/">www.i2p2.i2p</a> and mirror <a href="http://i2p-projekt.i2p">i2p-projekt.i2p</a>:
|
||||
secure and anonymous connections to <a href="http://www.i2p2.de/">www.i2p2.de</a></li>
|
||||
<li><a href="http://eepsites.i2p/">eepsites.i2p</a>: an anonymously hosted search engine of eepsites</li>
|
||||
<li><a href="http://ugha.i2p/">ugha.i2p</a>: ugha's eepsite, a wiki that anyone can edit, and lots of links</li>
|
||||
<li><a href="http://dev.i2p/">dev.i2p</a>: a secure and anonymous connection to <a href="http://dev.i2p.net/">dev.i2p.net</a></li>
|
||||
<li>Freenet proxy: <a href="http://fproxy.tino.i2p">fproxy.tino.i2p</a></li>
|
||||
<li><a href="http://fproxy.tino.i2p">fproxy.tino.i2p</a>: Freenet proxy</li>
|
||||
</ul>
|
||||
There are many more eepsites - just follow the links from the ones you see,
|
||||
bookmark your favorites, and visit them often!</li>
|
||||
@ -55,10 +55,10 @@ Detailed instructions for starting your eepsite are on
|
||||
<p>Be patient - I2P may be slow to start the first time as it searches for peers.
|
||||
If, after 30 minutes, your Active: connected/recent count has less than 10 connected
|
||||
peers, you should open port 8887 on your firewall for better connectivity.
|
||||
If you cannot see any eepsites at all (even <a href="http://www.i2p">www.i2p</a>),
|
||||
If you cannot see any eepsites at all (even <a href="http://www.i2p2.i2p">www.i2p2.i2p</a>),
|
||||
be sure your browser proxy is set to localhost port 4444.
|
||||
You may also want to review the information on the
|
||||
<a href="http://www.i2p.net/">I2P website</a>, post up messages to the
|
||||
<a href="http://www.i2p2.i2p/">I2P website</a>, post up messages to the
|
||||
<a href="http://forum.i2p.net/">I2P discussion forum</a>, or swing by #i2p or
|
||||
#i2p-chat on IRC at <a href="irc://irc.freenode.net/#i2p">irc.freenode.net</a>, irc.postman.i2p or irc.freshcoffee.i2p (they're linked together).</p>
|
||||
|
||||
|
@ -939,6 +939,10 @@ public class Router {
|
||||
for (Iterator iter = ordered.iterator() ; iter.hasNext(); ) {
|
||||
String key = (String)iter.next();
|
||||
String val = _config.getProperty(key);
|
||||
// Escape line breaks before saving.
|
||||
// Remember: "\" needs escaping both for regex and string.
|
||||
val = val.replaceAll("\\r","\\\\r");
|
||||
val = val.replaceAll("\\n","\\\\n");
|
||||
buf.append(key).append('=').append(val).append('\n');
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.528 $ $Date: 2007-10-07 21:36:20 $";
|
||||
public final static String VERSION = "0.6.1.30";
|
||||
public final static String ID = "$Revision: 1.548 $ $Date: 2008-02-10 15:00:00 $";
|
||||
public final static String VERSION = "0.6.1.31";
|
||||
public final static long BUILD = 0;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||
|
@ -463,8 +463,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
}
|
||||
tunnel = (TunnelInfo) _tunnelCache.get(to);
|
||||
if (tunnel != null) {
|
||||
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel) &&
|
||||
(tunnel.getLength() <= 1 || !getContext().commSystem().isBacklogged(tunnel.getPeer(1))))
|
||||
if (getContext().tunnelManager().isValidTunnel(_from.calculateHash(), tunnel))
|
||||
return(tunnel);
|
||||
else
|
||||
_tunnelCache.remove(to);
|
||||
|
@ -91,12 +91,12 @@ class ProfileOrganizerRenderer {
|
||||
buf.append("<tr>");
|
||||
buf.append("<td><code>");
|
||||
if (prof.getIsFailing()) {
|
||||
buf.append("<font color=\"red\">--").append(peer.toBase64().substring(0,6)).append("</font>");
|
||||
buf.append("<font color=\"red\">-- ").append(peer.toBase64().substring(0,6)).append("</font>");
|
||||
} else {
|
||||
if (prof.getIsActive()) {
|
||||
buf.append("<font color=\"blue\">++").append(peer.toBase64().substring(0,6)).append("</font>");
|
||||
buf.append("<font color=\"blue\">++ ").append(peer.toBase64().substring(0,6)).append("</font>");
|
||||
} else {
|
||||
buf.append("__").append(peer.toBase64().substring(0,6));
|
||||
buf.append(" ").append(peer.toBase64().substring(0,6));
|
||||
}
|
||||
}
|
||||
buf.append("</code></td>");
|
||||
|
@ -124,8 +124,8 @@ public class EventPumper implements Runnable {
|
||||
|
||||
int failsafeWrites = 0;
|
||||
int failsafeCloses = 0;
|
||||
|
||||
long expireIdleWriteTime = 60*60*1000l + _context.random().nextLong(60*60*1000l);
|
||||
// pointless if we do this every 2 seconds?
|
||||
long expireIdleWriteTime = 20*60*1000l; // + _context.random().nextLong(60*60*1000l);
|
||||
for (Iterator iter = all.iterator(); iter.hasNext(); ) {
|
||||
try {
|
||||
SelectionKey key = (SelectionKey)iter.next();
|
||||
@ -143,7 +143,7 @@ public class EventPumper implements Runnable {
|
||||
failsafeWrites++;
|
||||
}
|
||||
|
||||
if ( (con.getTimeSinceSend() > expireIdleWriteTime) && (con.getMessagesSent() > 0) ) {
|
||||
if ( con.getTimeSinceSend() > expireIdleWriteTime) {
|
||||
// we haven't sent anything in a really long time, so lets just close 'er up
|
||||
con.close();
|
||||
failsafeCloses++;
|
||||
|
@ -111,6 +111,8 @@ public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(getClass());
|
||||
_created = System.currentTimeMillis();
|
||||
_lastSendTime = _created;
|
||||
_lastReceiveTime = _created;
|
||||
_transport = transport;
|
||||
_chan = chan;
|
||||
_readBufs = new ArrayList(4);
|
||||
@ -204,8 +206,8 @@ public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {
|
||||
return queued;
|
||||
}
|
||||
}
|
||||
public long getTimeSinceSend() { return _lastSendTime <= 0 ? 0 : System.currentTimeMillis()-_lastSendTime; }
|
||||
public long getTimeSinceReceive() { return _lastReceiveTime <= 0 ? 0 : System.currentTimeMillis()-_lastReceiveTime; }
|
||||
public long getTimeSinceSend() { return System.currentTimeMillis()-_lastSendTime; }
|
||||
public long getTimeSinceReceive() { return System.currentTimeMillis()-_lastReceiveTime; }
|
||||
public long getTimeSinceCreated() { return System.currentTimeMillis()-_created; }
|
||||
public int getConsecutiveBacklog() { return _consecutiveBacklog; }
|
||||
|
||||
|
Reference in New Issue
Block a user