I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 2c594357 authored by jrandom's avatar jrandom Committed by zzz
Browse files

2004-11-21 jrandom

    * Allow end of line comments in the hosts.txt and other config files,
      using '#' to begin the comments (thanks susi!)
    * Add support to I2PTunnel's 'client' feature for picking between multiple
      target destinations (e.g. 'client 6668 irc.duck.i2p,irc.baffled.i2p')
    * Add a quick link on the left hand nav to reseed if there aren't enough
      known peers, as well as link to the config page if there are no active
      peers.  Revised config page accordingly.
parent 7336bf5c
No related branches found
No related tags found
No related merge requests found
...@@ -284,7 +284,7 @@ public class I2PTunnel implements Logging, EventDispatcher { ...@@ -284,7 +284,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("textserver <host> <port> <privkey>"); l.log("textserver <host> <port> <privkey>");
l.log("genkeys <privkeyfile> [<pubkeyfile>]"); l.log("genkeys <privkeyfile> [<pubkeyfile>]");
l.log("gentextkeys"); l.log("gentextkeys");
l.log("client <port> <pubkey>|file:<pubkeyfile>"); l.log("client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile>");
l.log("httpclient <port>"); l.log("httpclient <port>");
l.log("lookup <name>"); l.log("lookup <name>");
l.log("quit"); l.log("quit");
...@@ -449,9 +449,11 @@ public class I2PTunnel implements Logging, EventDispatcher { ...@@ -449,9 +449,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
notifyEvent("clientTaskId", new Integer(-1)); notifyEvent("clientTaskId", new Integer(-1));
} }
} else { } else {
l.log("client <port> <pubkey>|file:<pubkeyfile>"); l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>");
l.log(" creates a client that forwards port to the pubkey.\n" l.log(" creates a client that forwards port to the pubkey.\n"
+ " use 0 as port to get a free port assigned."); + " use 0 as port to get a free port assigned. If you specify\n"
+ " a comma delimited list of pubkeys, it will rotate among them\n"
+ " randomlyl");
notifyEvent("clientTaskId", new Integer(-1)); notifyEvent("clientTaskId", new Integer(-1));
} }
} }
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
package net.i2p.i2ptunnel; package net.i2p.i2ptunnel;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.DataFormatException; import net.i2p.data.DataFormatException;
import net.i2p.data.Destination; import net.i2p.data.Destination;
...@@ -15,15 +19,17 @@ public class I2PTunnelClient extends I2PTunnelClientBase { ...@@ -15,15 +19,17 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
private static final Log _log = new Log(I2PTunnelClient.class); private static final Log _log = new Log(I2PTunnelClient.class);
protected Destination dest; /** list of Destination objects that we point at */
protected List dests;
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1 private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
protected long readTimeout = DEFAULT_READ_TIMEOUT; protected long readTimeout = DEFAULT_READ_TIMEOUT;
/** /**
* @param destinations comma delimited list of peers we target
* @throws IllegalArgumentException if the I2PTunnel does not contain * @throws IllegalArgumentException if the I2PTunnel does not contain
* valid config to contact the router * valid config to contact the router
*/ */
public I2PTunnelClient(int localPort, String destination, Logging l, public I2PTunnelClient(int localPort, String destinations, Logging l,
boolean ownDest, EventDispatcher notifyThis, boolean ownDest, EventDispatcher notifyThis,
I2PTunnel tunnel) throws IllegalArgumentException { I2PTunnel tunnel) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, "SynSender", tunnel); super(localPort, ownDest, l, notifyThis, "SynSender", tunnel);
...@@ -33,19 +39,28 @@ public class I2PTunnelClient extends I2PTunnelClientBase { ...@@ -33,19 +39,28 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
return; return;
} }
try { StringTokenizer tok = new StringTokenizer(destinations, ",");
dest = I2PTunnel.destFromName(destination); dests = new ArrayList(1);
if (dest == null) { while (tok.hasMoreTokens()) {
l.log("Could not resolve " + destination + "."); String destination = tok.nextToken();
return; try {
Destination dest = I2PTunnel.destFromName(destination);
if (dest == null)
l.log("Could not resolve " + destination);
else
dests.add(dest);
} catch (DataFormatException dfe) {
l.log("Bad format parsing \"" + destination + "\"");
} }
} catch (DataFormatException e) { }
l.log("Bad format in destination \"" + destination + "\".");
if (dests.size() <= 0) {
l.log("No target destinations found");
notifyEvent("openClientResult", "error"); notifyEvent("openClientResult", "error");
return; return;
} }
setName(getLocalPort() + " -> " + destination); setName(getLocalPort() + " -> " + destinations);
startRunning(); startRunning();
...@@ -56,6 +71,7 @@ public class I2PTunnelClient extends I2PTunnelClientBase { ...@@ -56,6 +71,7 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
public long getReadTimeout() { return readTimeout; } public long getReadTimeout() { return readTimeout; }
protected void clientConnectionRun(Socket s) { protected void clientConnectionRun(Socket s) {
Destination dest = pickDestination();
I2PSocket i2ps = null; I2PSocket i2ps = null;
try { try {
i2ps = createI2PSocket(dest); i2ps = createI2PSocket(dest);
...@@ -72,4 +88,17 @@ public class I2PTunnelClient extends I2PTunnelClientBase { ...@@ -72,4 +88,17 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
} }
} }
} }
private final Destination pickDestination() {
int size = dests.size();
if (size <= 0) {
if (_log.shouldLog(Log.ERROR))
_log.error("No client targets?!");
return null;
}
if (size == 1) // skip the rand in the most common case
return (Destination)dests.get(0);
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
return (Destination)dests.get(index);
}
} }
package net.i2p.router.web;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Handler to deal with reseed requests. This reseed from the URL
* http://dev.i2p.net/i2pdb/ unless the java env property "i2p.reseedURL" is
* set. It always writes to ./netDb/, so don't mess with that.
*
*/
public class ReseedHandler {
private static ReseedRunner _reseedRunner = new ReseedRunner();
public void setReseedNonce(String nonce) {
if (nonce == null) return;
if (nonce.equals(System.getProperty("net.i2p.router.web.ReseedHandler.nonce")) ||
nonce.equals(System.getProperty("net.i2p.router.web.ReseedHandler.noncePrev"))) {
synchronized (_reseedRunner) {
if (_reseedRunner.isRunning()) {
return;
} else {
System.setProperty("net.i2p.router.web.ReseedHandler.reseedInProgress", "true");
I2PThread reseed = new I2PThread(_reseedRunner, "Reseed");
reseed.start();
}
}
}
}
public static class ReseedRunner implements Runnable {
private boolean _isRunning;
public ReseedRunner() { _isRunning = false; }
public boolean isRunning() { return _isRunning; }
public void run() {
_isRunning = true;
reseed();
System.setProperty("net.i2p.router.web.ReseedHandler.reseedInProgress", "false");
_isRunning = false;
}
}
private static final String DEFAULT_SEED_URL = "http://dev.i2p.net/i2pdb/";
/**
* Reseed has been requested, so lets go ahead and do it. Fetch all of
* the routerInfo-*.dat files from the specified URL (or the default) and
* save them into this router's netDb dir.
*
*/
private static void reseed() {
String seedURL = System.getProperty("i2p.reseedURL", DEFAULT_SEED_URL);
if ( (seedURL == null) || (seedURL.trim().length() <= 0) )
seedURL = DEFAULT_SEED_URL;
try {
URL dir = new URL(seedURL);
String content = new String(readURL(dir));
Set urls = new HashSet();
int cur = 0;
while (true) {
int start = content.indexOf("href=\"routerInfo-", cur);
if (start < 0)
break;
int end = content.indexOf(".dat\">", start);
String name = content.substring(start+"href=\"routerInfo-".length(), end);
urls.add(name);
cur = end + 1;
}
int fetched = 0;
int errors = 0;
for (Iterator iter = urls.iterator(); iter.hasNext(); ) {
try {
fetchSeed(seedURL, (String)iter.next());
fetched++;
} catch (Exception e) {
errors++;
}
}
} catch (Throwable t) {
I2PAppContext.getGlobalContext().logManager().getLog(ReseedHandler.class).error("Error reseeding", t);
}
}
private static void fetchSeed(String seedURL, String peer) throws Exception {
URL url = new URL(seedURL + (seedURL.endsWith("/") ? "" : "/") + "routerInfo-" + peer + ".dat");
byte data[] = readURL(url);
writeSeed(peer, data);
}
private static byte[] readURL(URL url) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
byte buf[] = new byte[1024];
while (true) {
int read = in.read(buf);
if (read < 0)
break;
baos.write(buf, 0, read);
}
in.close();
return baos.toByteArray();
}
private static void writeSeed(String name, byte data[]) throws Exception {
String dirName = "netDb"; // _context.getProperty("router.networkDatabase.dbDir", "netDb");
File netDbDir = new File(dirName);
if (!netDbDir.exists()) {
boolean ok = netDbDir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(new File(netDbDir, "routerInfo-" + name + ".dat"));
fos.write(data);
fos.close();
}
}
...@@ -28,44 +28,58 @@ ...@@ -28,44 +28,58 @@
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce")%>" /> <input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigNetHandler.nonce")%>" />
<input type="hidden" name="action" value="blah" /> <input type="hidden" name="action" value="blah" />
<b>External hostname/IP address:</b> TCP port:
<input name="hostname" type="text" size="32" value="<jsp:getProperty name="nethelper" property="hostname" />" />
<input type="submit" name="guesshost" value="Guess" /><br />
<b>Externally reachable TCP port:</b>
<input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br /> <input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br />
<i>The hostname/IP address and TCP port must be reachable from the outside world. If <b>You must poke a hole in your firewall or NAT (if applicable) so that you can receive inbound TCP
you are behind a firewall or NAT, this means you must poke a hole for this port. If connections on it.</b> Nothing will work if you don't. Sorry. We know how to make it so
you are using DHCP and do not have a static IP address, you should either use a service like this restriction won't be necessary, but its later on in the
<a href="http://dyndns.org/">dyndns</a> or leave the hostname blank. If you leave it blank, <a href="http://www.i2p.net/roadmap">roadmap</a> and we only have so many coder-hours (but if you want
your router will autodetect the 'correct' IP address by asking a peer (and unconditionally to help, please <a href="http://www.i2p.net/getinvolved">get involved!</a>)
believing them if the address is routable and you don't have any established connections yet).
The "guess" functionality makes an HTTP request
to <a href="http://www.whatismyip.com/">www.whatismyip.com</a>.</i>
<hr />
<b>Enable internal time synchronization?</b> <input type="checkbox" <jsp:getProperty name="nethelper" property="enableTimeSyncChecked" /> name="enabletimesync" /><br />
<i>If disabled, your machine <b>must</b> be NTP synchronized - your clock must always
be within a few seconds of "correct".</i>
<hr /> <hr />
<b>Bandwidth limiter</b><br /> <b>Bandwidth limiter</b><br />
<b>Inbound rate</b>: Inbound rate:
<input name="inboundrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="inboundRate" />" /> KBytes per second<br /> <input name="inboundrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="inboundRate" />" /> KBytes per second<br />
<b>Inbound burst duration:</b> Inbound burst duration:
<jsp:getProperty name="nethelper" property="inboundBurstFactorBox" /><br /> <jsp:getProperty name="nethelper" property="inboundBurstFactorBox" /><br />
<b>Outbound rate:</b> Outbound rate:
<input name="outboundrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="outboundRate" />" /> KBytes per second<br /> <input name="outboundrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="outboundRate" />" /> KBytes per second<br />
<b>Outbound burst duration:</b> Outbound burst duration:
<jsp:getProperty name="nethelper" property="outboundBurstFactorBox" /><br /> <jsp:getProperty name="nethelper" property="outboundBurstFactorBox" /><br />
<i>A negative rate means there is no limit</i><br /> <i>A negative rate means there is no limit</i><br />
<hr /> <hr />
<b>Reseed</b> (from <input name="reseedfrom" type="text" size="40" value="http://dev.i2p.net/i2pdb/" />): Enable internal time synchronization? <input type="checkbox" <jsp:getProperty name="nethelper" property="enableTimeSyncChecked" /> name="enabletimesync" /><br />
<input type="submit" name="reseed" value="now" /><br /> <i>If disabled, your machine <b>must</b> be NTP synchronized - your clock must always
<i>May take some time to download the peer references</i> be within a few seconds of "correct". You will need to be able to send outbound UDP
packets on port 123 to one of the pool.ntp.org machines (or some other SNTP server).</i>
<hr /> <hr />
<input type="submit" name="save" value="Save changes" /> <input type="reset" value="Cancel" /><br /> <input type="submit" name="save" value="Save changes" /> <input type="reset" value="Cancel" /><br />
<i>Changing the hostname or TCP port will force a 'soft restart' - dropping your connections <i>Changing the TCP port will force a 'soft restart' - dropping your connections and clients as
and clients as if the router was stopped and restarted. <b>Please be patient</b> - it may take if the router was stopped and restarted. <b>Please be patient</b> - it may take
a few seconds to complete.</i> a few seconds to complete.</i>
</form> </form>
<hr />
<b>Advanced network config:</b>
<p>
There are two other network settings, but no one reads this text so there's no reason
to tell you about them. In case you actually do read this, here's the deal: by default,
I2P will attempt to guess your IP address by having whomever it talks to tell it what
address they think you are. If and only if you have no working TCP connections and you
have not overridden the IP address, your router will believe them. If that doesn't sound
ok to you, thats fine - go to the <a href="/configadvanced.jsp">advanced config</a> page
and add "i2np.tcp.hostname=yourHostname", then go to the
<a href="/configservice.jsp">service</a> page and do a graceful restart. We used to make
people enter a hostname/IP address on this page, but too many people got it wrong ;)</p>
<p>The other advanced network option has to do with reseeding - you should never need to
reseed your router as long as you can find at least one other peer on the network. However,
when you do need to reseed, a link will show up on the left hand side which will
fetch all of the routerInfo-* files from http://dev.i2p.net/i2pdb/. That URL is just an
apache folder pointing at the netDb/ directory of a router - anyone can run one, and you can
configure your router to seed off an alternate URL by adding the java environmental property
"i2p.reseedURL=someURL" (e.g. java -Di2p.reseedURL=http://dev.i2p.net/i2pdb/ ...). You can
also do it manually by getting routerInfo-*.dat files from someone (a friend, someone on IRC,
whatever) and saving them to your netDb/ directory.</p>
</div> </div>
</body> </body>
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" /> <jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" />
<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" /> <jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
<jsp:useBean class="net.i2p.router.web.ReseedHandler" id="reseed" scope="request" />
<jsp:setProperty name="reseed" property="*" />
<div class="routersummary"> <div class="routersummary">
<u><b>General</b></u><br /> <u><b>General</b></u><br />
<b>Ident:</b> <jsp:getProperty name="helper" property="ident" /><br /> <b>Ident:</b> <jsp:getProperty name="helper" property="ident" /><br />
...@@ -16,8 +19,27 @@ ...@@ -16,8 +19,27 @@
<b>High capacity:</b> <jsp:getProperty name="helper" property="highCapacityPeers" /><br /> <b>High capacity:</b> <jsp:getProperty name="helper" property="highCapacityPeers" /><br />
<b>Well integrated:</b> <jsp:getProperty name="helper" property="wellIntegratedPeers" /><br /> <b>Well integrated:</b> <jsp:getProperty name="helper" property="wellIntegratedPeers" /><br />
<b>Failing:</b> <jsp:getProperty name="helper" property="failingPeers" /><br /> <b>Failing:</b> <jsp:getProperty name="helper" property="failingPeers" /><br />
<b>Shitlisted:</b> <jsp:getProperty name="helper" property="shitlistedPeers" /><br /> <b>Shitlisted:</b> <jsp:getProperty name="helper" property="shitlistedPeers" /><br /><%
<hr /> if (helper.getActivePeers() <= 0) {
%><b><a href="config.jsp">check your NAT/firewall</a></b><br /><%
}
if (helper.getActiveProfiles() <= 4) { // 4 is the min fallback
if ("true".equals(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress", "false"))) {
out.print(" <i>reseeding</i>");
} else {
long nonce = new java.util.Random().nextLong();
String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
String uri = request.getRequestURI();
if (uri.indexOf('?') > 0)
uri = uri + "&reseedNonce=" + nonce;
else
uri = uri + "?reseedNonce=" + nonce;
out.print(" <a href=\"" + uri + "\">reseed</a>");
}
}
%><hr />
<u><b>Bandwidth in/out</b></u><br /> <u><b>Bandwidth in/out</b></u><br />
<b>1m:</b> <jsp:getProperty name="helper" property="inboundMinuteKBps" />/<jsp:getProperty name="helper" property="outboundMinuteKBps" />KBps<br /> <b>1m:</b> <jsp:getProperty name="helper" property="inboundMinuteKBps" />/<jsp:getProperty name="helper" property="outboundMinuteKBps" />KBps<br />
......
...@@ -154,6 +154,9 @@ public class DataHelper { ...@@ -154,6 +154,9 @@ public class DataHelper {
while ( (line = in.readLine()) != null) { while ( (line = in.readLine()) != null) {
if (line.trim().length() <= 0) continue; if (line.trim().length() <= 0) continue;
if (line.charAt(0) == '#') continue; if (line.charAt(0) == '#') continue;
if (line.charAt(0) == ';') continue;
if (line.indexOf('#') > 0) // trim off any end of line comment
line = line.substring(0, line.indexOf('#')).trim();
int split = line.indexOf('='); int split = line.indexOf('=');
if (split <= 0) continue; if (split <= 0) continue;
String key = line.substring(0, split); String key = line.substring(0, split);
...@@ -311,7 +314,7 @@ public class DataHelper { ...@@ -311,7 +314,7 @@ public class DataHelper {
throw new IllegalArgumentException("wtf, fromLong got a negative? " + rv + ": offset="+ offset +" numBytes="+numBytes); throw new IllegalArgumentException("wtf, fromLong got a negative? " + rv + ": offset="+ offset +" numBytes="+numBytes);
return rv; return rv;
} }
public static void main(String args[]) { public static void main(String args[]) {
for (int i = 0; i <= 0xFF; i++) for (int i = 0; i <= 0xFF; i++)
testLong(1, i); testLong(1, i);
......
$Id: history.txt,v 1.76 2004/11/19 18:04:27 jrandom Exp $ $Id: history.txt,v 1.77 2004/11/20 23:08:14 jrandom Exp $
2004-11-21 jrandom
* Allow end of line comments in the hosts.txt and other config files,
using '#' to begin the comments (thanks susi!)
* Add support to I2PTunnel's 'client' feature for picking between multiple
target destinations (e.g. 'client 6668 irc.duck.i2p,irc.baffled.i2p')
* Add a quick link on the left hand nav to reseed if there aren't enough
known peers, as well as link to the config page if there are no active
peers. Revised config page accordingly.
2004-11-21 jrandom 2004-11-21 jrandom
* Destroy ElGamal/AES+SessionTag keys after 15 minutes of inactivity * Destroy ElGamal/AES+SessionTag keys after 15 minutes of inactivity
......
...@@ -15,9 +15,9 @@ import net.i2p.CoreVersion; ...@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.81 $ $Date: 2004/11/19 18:04:27 $"; public final static String ID = "$Revision: 1.82 $ $Date: 2004/11/20 23:08:14 $";
public final static String VERSION = "0.4.1.4"; public final static String VERSION = "0.4.1.4";
public final static long BUILD = 10; public final static long BUILD = 11;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION); System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment