forked from I2P_Developers/i2p.i2p
* 2005-07-27 0.6 released
2005-07-27 jrandom * Enabled SSU as the default top priority transport, adjusting the config.jsp page accordingly. * Add verification fields to the SSU and TCP connection negotiation (not compatible with previous builds) * Enable the backwards incompatible tunnel crypto change as documented in tunnel-alt.html (have each hop encrypt the received IV before using it, then encrypt it again before sending it on) * Disable the I2CP encryption, leaving in place the end to end garlic encryption (another backwards incompatible change) * Adjust the protocol versions on the TCP and SSU transports so that they won't talk to older routers. * Fix up the config stats handling again * Fix a rare off-by-one in the SSU fragmentation * Reduce some unnecessary netDb resending by inluding the peers queried successfully in the store redundancy count.
This commit is contained in:
@ -1,445 +0,0 @@
|
|||||||
/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java)
|
|
||||||
* (c) 2003 - 2004 mihi
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.i2p.i2ptunnel;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.ServerSocket;
|
|
||||||
import java.net.Socket;
|
|
||||||
|
|
||||||
import net.i2p.data.DataFormatException;
|
|
||||||
import net.i2p.data.Destination;
|
|
||||||
import net.i2p.util.Clock;
|
|
||||||
import net.i2p.util.I2PThread;
|
|
||||||
import net.i2p.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quick and dirty socket listener to control an I2PTunnel.
|
|
||||||
* Basically run this class as TunnelManager [listenHost] [listenPort] and
|
|
||||||
* then send it commands on that port. Commands are one shot deals -
|
|
||||||
* Send a command + newline, get a response plus newline, then get disconnected.
|
|
||||||
* <p />
|
|
||||||
* <b>Implemented commands:</b>
|
|
||||||
* <pre>
|
|
||||||
* -------------------------------------------------
|
|
||||||
* lookup <name>\n
|
|
||||||
* --
|
|
||||||
* <base64 of the destination>\n
|
|
||||||
* or
|
|
||||||
* <error message, usually 'Unknown host'>\n
|
|
||||||
*
|
|
||||||
* Lookup the public key of a named destination (i.e. listed in hosts.txt)
|
|
||||||
* -------------------------------------------------
|
|
||||||
* genkey\n
|
|
||||||
* --
|
|
||||||
* <base64 of the destination>\t<base64 of private data>\n
|
|
||||||
*
|
|
||||||
* Generates a new public and private key pair
|
|
||||||
* -------------------------------------------------
|
|
||||||
* convertprivate <base64 of privkey>
|
|
||||||
* --
|
|
||||||
* <base64 of destination>\n
|
|
||||||
* or
|
|
||||||
* <error message>\n
|
|
||||||
*
|
|
||||||
* Returns the destination (pubkey) of a given private key.
|
|
||||||
* -------------------------------------------------
|
|
||||||
* listen_on <ip>\n
|
|
||||||
* --
|
|
||||||
* ok\n
|
|
||||||
* or
|
|
||||||
* error\n
|
|
||||||
*
|
|
||||||
* Sets the ip address clients will listen on. By default this is the
|
|
||||||
* localhost (127.0.0.1)
|
|
||||||
* -------------------------------------------------
|
|
||||||
* openclient <listenPort> <peer>[ <sharedClient>]\n
|
|
||||||
* --
|
|
||||||
* ok [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* ok <listenPort> [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* error\n
|
|
||||||
*
|
|
||||||
* Open a tunnel on the given <listenport> to the destination specified
|
|
||||||
* by <peer>. If <listenPort> is 0 a free port is picked and returned in
|
|
||||||
* the reply message. Otherwise the short reply message is used.
|
|
||||||
* Peer can be the base64 of the destination, a file with the public key
|
|
||||||
* specified as 'file:<filename>' or the name of a destination listed in
|
|
||||||
* hosts.txt. The <jobId> returned together with "ok" and <listenport> can
|
|
||||||
* later be used as argument for the "close" command.
|
|
||||||
* <sharedClient> indicates if this httpclient shares tunnels with other
|
|
||||||
* clients or not (just use 'true' and 'false'
|
|
||||||
* -------------------------------------------------
|
|
||||||
* openhttpclient <listenPort> [<sharedClient>] [<proxy>]\n
|
|
||||||
* --
|
|
||||||
* ok [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* ok <listenPort> [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* error\n
|
|
||||||
*
|
|
||||||
* Open an HTTP proxy through the I2P on the given
|
|
||||||
* <listenport>. <proxy> (optional) specifies a
|
|
||||||
* destination to be used as an outbound proxy, to access normal WWW
|
|
||||||
* sites out of the .i2p domain. If <listenPort> is 0 a free
|
|
||||||
* port is picked and returned in the reply message. Otherwise the
|
|
||||||
* short reply message is used. <proxy> can be the base64 of the
|
|
||||||
* destination, a file with the public key specified as
|
|
||||||
* 'file:<filename>' or the name of a destination listed in
|
|
||||||
* hosts.txt. The <jobId> returned together with "ok" and
|
|
||||||
* <listenport> can later be used as argument for the "close"
|
|
||||||
* command.
|
|
||||||
* <sharedClient> indicates if this httpclient shares tunnels with other
|
|
||||||
* clients or not (just use 'true' and 'false'
|
|
||||||
* -------------------------------------------------
|
|
||||||
* opensockstunnel <listenPort>\n
|
|
||||||
* --
|
|
||||||
* ok [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* ok <listenPort> [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* error\n
|
|
||||||
*
|
|
||||||
* Open an SOCKS tunnel through the I2P on the given
|
|
||||||
* <listenport>. If <listenPort> is 0 a free port is
|
|
||||||
* picked and returned in the reply message. Otherwise the short
|
|
||||||
* reply message is used. The <jobId> returned together with
|
|
||||||
* "ok" and <listenport> can later be used as argument for the
|
|
||||||
* "close" command.
|
|
||||||
* -------------------------------------------------
|
|
||||||
* openserver <serverHost> <serverPort> <serverKeys>\n
|
|
||||||
* --
|
|
||||||
* ok [<jobId>]\n
|
|
||||||
* or
|
|
||||||
* error\n
|
|
||||||
*
|
|
||||||
* Starts receiving traffic for the destination specified by <serverKeys>
|
|
||||||
* and forwards it to the <serverPort> of <serverHost>.
|
|
||||||
* <serverKeys> is the base 64 encoded private key set of the local
|
|
||||||
* destination. The <joId> returned together with "ok" can later be used
|
|
||||||
* as argument for the "close" command.
|
|
||||||
* -------------------------------------------------
|
|
||||||
* close [forced] <jobId>\n
|
|
||||||
* or
|
|
||||||
* close [forced] all\n
|
|
||||||
* --
|
|
||||||
* ok\n
|
|
||||||
* or
|
|
||||||
* error\n
|
|
||||||
*
|
|
||||||
* Closes the job specified by <jobId> or all jobs. Use the list command
|
|
||||||
* for a list of running jobs.
|
|
||||||
* Normally a connection job is not closed when it still has an active
|
|
||||||
* connection. Use the optional 'forced' keyword to close connections
|
|
||||||
* regardless of their use.
|
|
||||||
* -------------------------------------------------
|
|
||||||
* list\n
|
|
||||||
* --
|
|
||||||
* Example output:
|
|
||||||
*
|
|
||||||
* [0] i2p.dnsalias.net/69.55.226.145:5555 <- C:\i2pKeys\squidPriv
|
|
||||||
* [1] 8767 -> HTTPClient
|
|
||||||
* [2] 7575 -> file:C:\i2pKeys\squidPub
|
|
||||||
* [3] 5252 -> sCcSANIO~f4AQtCNI1BvDp3ZBS~9Ag5O0k0Msm7XBWWz5eOnZWL3MQ-2rxlesucb9XnpASGhWzyYNBpWAfaIB3pux1J1xujQLOwscMIhm7T8BP76Ly5jx6BLZCYrrPj0BI0uV90XJyT~4UyQgUlC1jzFQdZ9HDgBPJDf1UI4-YjIwEHuJgdZynYlQ1oUFhgno~HhcDByXO~PDaO~1JDMDbBEfIh~v6MgmHp-Xchod1OfKFrxFrzHgcJbn7E8edTFjZA6JCi~DtFxFelQz1lSBd-QB1qJnA0g-pVL5qngNUojXJCXs4qWcQ7ICLpvIc-Fpfj-0F1gkVlGDSGkb1yLH3~8p4czYgR3W5D7OpwXzezz6clpV8kmbd~x2SotdWsXBPRhqpewO38coU4dJG3OEUbuYmdN~nJMfWbmlcM1lXzz2vBsys4sZzW6dV3hZnbvbfxNTqbdqOh-KXi1iAzXv7CVTun0ubw~CfeGpcAqutC5loRUq7Mq62ngOukyv8Z9AAAA
|
|
||||||
*
|
|
||||||
* Lists descriptions of all running jobs. The exact format of the
|
|
||||||
* description depends on the type of job.
|
|
||||||
* -------------------------------------------------
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @deprecated this isn't run by default, and no one seems to use it, and has
|
|
||||||
* lots of things to maintain. so, at some point this may dissapear
|
|
||||||
* unless someone pipes up ;)
|
|
||||||
*/
|
|
||||||
public class TunnelManager implements Runnable {
|
|
||||||
private final static Log _log = new Log(TunnelManager.class);
|
|
||||||
private I2PTunnel _tunnel;
|
|
||||||
private ServerSocket _socket;
|
|
||||||
private boolean _keepAccepting;
|
|
||||||
|
|
||||||
public TunnelManager(int listenPort) {
|
|
||||||
this(null, listenPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TunnelManager(String listenHost, int listenPort) {
|
|
||||||
_tunnel = new I2PTunnel();
|
|
||||||
_keepAccepting = true;
|
|
||||||
try {
|
|
||||||
if (listenHost != null) {
|
|
||||||
_socket = new ServerSocket(listenPort, 0, InetAddress.getByName(listenHost));
|
|
||||||
_log.info("Listening for tunnel management clients on " + listenHost + ":" + listenPort);
|
|
||||||
} else {
|
|
||||||
_socket = new ServerSocket(listenPort);
|
|
||||||
_log.info("Listening for tunnel management clients on localhost:" + listenPort);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
_log.error("Error starting up tunnel management listener on " + listenPort, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String args[]) {
|
|
||||||
int port = 7676;
|
|
||||||
String host = null;
|
|
||||||
if (args.length == 1) {
|
|
||||||
try {
|
|
||||||
port = Integer.parseInt(args[0]);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
_log.error("Usage: TunnelManager [host] [port]");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (args.length == 2) {
|
|
||||||
host = args[0];
|
|
||||||
try {
|
|
||||||
port = Integer.parseInt(args[1]);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
_log.error("Usage: TunnelManager [host] [port]");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TunnelManager mgr = new TunnelManager(host, port);
|
|
||||||
Thread t = new I2PThread(mgr, "Listener");
|
|
||||||
t.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
if (_socket == null) {
|
|
||||||
_log.error("Unable to start listening, since the socket was not bound. Already running?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_log.debug("Running");
|
|
||||||
try {
|
|
||||||
while (_keepAccepting) {
|
|
||||||
Socket socket = _socket.accept();
|
|
||||||
_log.debug("Client accepted");
|
|
||||||
if (socket != null) {
|
|
||||||
Thread t = new I2PThread(new TunnelManagerClientRunner(this, socket));
|
|
||||||
t.setName("TunnelManager Client");
|
|
||||||
t.setPriority(I2PThread.MIN_PRIORITY);
|
|
||||||
t.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
_log.error("Error accepting connections", ioe);
|
|
||||||
} catch (Exception e) {
|
|
||||||
_log.error("Other error?!", e);
|
|
||||||
} finally {
|
|
||||||
if (_socket != null) try {
|
|
||||||
_socket.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(5000);
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void error(String msg, OutputStream out) throws IOException {
|
|
||||||
out.write(msg.getBytes());
|
|
||||||
out.write('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processQuit(OutputStream out) throws IOException {
|
|
||||||
out.write("Nice try".getBytes());
|
|
||||||
out.write('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processList(OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
long startCommand = Clock.getInstance().now();
|
|
||||||
_tunnel.runCommand("list", buf);
|
|
||||||
Object obj = _tunnel.waitEventValue("listDone");
|
|
||||||
long endCommand = Clock.getInstance().now();
|
|
||||||
String str = buf.getBuffer();
|
|
||||||
_log.debug("ListDone complete after " + (endCommand - startCommand) + "ms: [" + str + "]");
|
|
||||||
out.write(str.getBytes());
|
|
||||||
out.write('\n');
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processListenOn(String ip, OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("listen_on " + ip, buf);
|
|
||||||
String status = (String) _tunnel.waitEventValue("listen_onResult");
|
|
||||||
out.write((status + "\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* "lookup <name>" returns with the result in base64, else "Unknown host" [or something like that],
|
|
||||||
* then a newline.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void processLookup(String name, OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("lookup " + name, buf);
|
|
||||||
String rv = (String) _tunnel.waitEventValue("lookupResult");
|
|
||||||
out.write(rv.getBytes());
|
|
||||||
out.write('\n');
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processTestDestination(String destKey, OutputStream out) throws IOException {
|
|
||||||
try {
|
|
||||||
Destination d = new Destination();
|
|
||||||
d.fromBase64(destKey);
|
|
||||||
out.write("valid\n".getBytes());
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
out.write("invalid\n".getBytes());
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processConvertPrivate(String priv, OutputStream out) throws IOException {
|
|
||||||
try {
|
|
||||||
Destination dest = new Destination();
|
|
||||||
dest.fromBase64(priv);
|
|
||||||
String str = dest.toBase64();
|
|
||||||
out.write(str.getBytes());
|
|
||||||
out.write('\n');
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
_log.error("Error converting private data", dfe);
|
|
||||||
out.write("Error converting private key\n".getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processClose(String which, boolean forced, OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand((forced ? "close forced " : "close ") + which, buf);
|
|
||||||
String str = (String) _tunnel.waitEventValue("closeResult");
|
|
||||||
out.write((str + "\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* "genkey" returns with the base64 of the destination, followed by a tab, then the base64 of that
|
|
||||||
* destination's private keys, then a newline.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void processGenKey(OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("gentextkeys", buf);
|
|
||||||
String priv = (String) _tunnel.waitEventValue("privateKey");
|
|
||||||
String pub = (String) _tunnel.waitEventValue("publicDestination");
|
|
||||||
out.write((pub + "\t" + priv).getBytes());
|
|
||||||
out.write('\n');
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processOpenClient(int listenPort, String peer, String sharedClient, OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("client " + listenPort + " " + peer + " " + sharedClient, buf);
|
|
||||||
Integer taskId = (Integer) _tunnel.waitEventValue("clientTaskId");
|
|
||||||
if (taskId.intValue() < 0) {
|
|
||||||
out.write("error\n".getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String rv = (String) _tunnel.waitEventValue("openClientResult");
|
|
||||||
if (rv.equals("error")) {
|
|
||||||
out.write((rv + "\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listenPort != 0) {
|
|
||||||
out.write((rv + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Integer port = (Integer) _tunnel.waitEventValue("clientLocalPort");
|
|
||||||
out.write((rv + " " + port.intValue() + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processOpenHTTPClient(int listenPort, String sharedClient, String proxy, OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("httpclient " + listenPort + " " + sharedClient + " " + proxy, buf);
|
|
||||||
Integer taskId = (Integer) _tunnel.waitEventValue("httpclientTaskId");
|
|
||||||
if (taskId.intValue() < 0) {
|
|
||||||
out.write("error\n".getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String rv = (String) _tunnel.waitEventValue("openHTTPClientResult");
|
|
||||||
if (rv.equals("error")) {
|
|
||||||
out.write((rv + "\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listenPort != 0) {
|
|
||||||
out.write((rv + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Integer port = (Integer) _tunnel.waitEventValue("clientLocalPort");
|
|
||||||
out.write((rv + " " + port.intValue() + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processOpenSOCKSTunnel(int listenPort, OutputStream out) throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("sockstunnel " + listenPort, buf);
|
|
||||||
Integer taskId = (Integer) _tunnel.waitEventValue("sockstunnelTaskId");
|
|
||||||
if (taskId.intValue() < 0) {
|
|
||||||
out.write("error\n".getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String rv = (String) _tunnel.waitEventValue("openSOCKSTunnelResult");
|
|
||||||
if (rv.equals("error")) {
|
|
||||||
out.write((rv + "\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listenPort != 0) {
|
|
||||||
out.write((rv + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Integer port = (Integer) _tunnel.waitEventValue("clientLocalPort");
|
|
||||||
out.write((rv + " " + port.intValue() + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processOpenServer(String serverHost, int serverPort, String privateKeys, OutputStream out)
|
|
||||||
throws IOException {
|
|
||||||
BufferLogger buf = new BufferLogger();
|
|
||||||
_tunnel.runCommand("textserver " + serverHost + " " + serverPort + " " + privateKeys, buf);
|
|
||||||
Integer taskId = (Integer) _tunnel.waitEventValue("serverTaskId");
|
|
||||||
if (taskId.intValue() < 0) {
|
|
||||||
out.write("error\n".getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String rv = (String) _tunnel.waitEventValue("openServerResult");
|
|
||||||
|
|
||||||
if (rv.equals("error")) {
|
|
||||||
out.write((rv + "\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.write((rv + " [" + taskId.intValue() + "]\n").getBytes());
|
|
||||||
buf.ignoreFurtherActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frisbee.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void unknownCommand(String command, OutputStream out) throws IOException {
|
|
||||||
out.write("Unknown command: ".getBytes());
|
|
||||||
out.write(command.getBytes());
|
|
||||||
out.write("\n".getBytes());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,203 +0,0 @@
|
|||||||
/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java)
|
|
||||||
* (c) 2003 - 2004 mihi
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.i2p.i2ptunnel;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import net.i2p.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runner thread that reads commands from the socket and fires off commands to
|
|
||||||
* the TunnelManager
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class TunnelManagerClientRunner implements Runnable {
|
|
||||||
private final static Log _log = new Log(TunnelManagerClientRunner.class);
|
|
||||||
private TunnelManager _mgr;
|
|
||||||
private Socket _clientSocket;
|
|
||||||
|
|
||||||
public TunnelManagerClientRunner(TunnelManager mgr, Socket socket) {
|
|
||||||
_clientSocket = socket;
|
|
||||||
_mgr = mgr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
_log.debug("Client running");
|
|
||||||
try {
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(_clientSocket.getInputStream()));
|
|
||||||
OutputStream out = _clientSocket.getOutputStream();
|
|
||||||
|
|
||||||
String cmd = reader.readLine();
|
|
||||||
if (cmd != null) processCommand(cmd, out);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
_log.error("Error processing client commands", ioe);
|
|
||||||
} finally {
|
|
||||||
if (_clientSocket != null) try {
|
|
||||||
_clientSocket.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_log.debug("Client closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the command string and fire off the appropriate tunnelManager method,
|
|
||||||
* sending the results to the output stream
|
|
||||||
*/
|
|
||||||
private void processCommand(String command, OutputStream out) throws IOException {
|
|
||||||
_log.debug("Processing [" + command + "]");
|
|
||||||
StringTokenizer tok = new StringTokenizer(command);
|
|
||||||
if (!tok.hasMoreTokens()) {
|
|
||||||
_mgr.unknownCommand(command, out);
|
|
||||||
} else {
|
|
||||||
String cmd = tok.nextToken();
|
|
||||||
if ("quit".equalsIgnoreCase(cmd)) {
|
|
||||||
_mgr.processQuit(out);
|
|
||||||
} else if ("lookup".equalsIgnoreCase(cmd)) {
|
|
||||||
if (tok.hasMoreTokens())
|
|
||||||
_mgr.processLookup(tok.nextToken(), out);
|
|
||||||
else
|
|
||||||
_mgr.error("Usage: lookup <hostname>", out);
|
|
||||||
} else if ("testdestination".equalsIgnoreCase(cmd)) {
|
|
||||||
if (tok.hasMoreTokens())
|
|
||||||
_mgr.processTestDestination(tok.nextToken(), out);
|
|
||||||
else
|
|
||||||
_mgr.error("Usage: testdestination <publicDestination>", out);
|
|
||||||
} else if ("convertprivate".equalsIgnoreCase(cmd)) {
|
|
||||||
if (tok.hasMoreTokens())
|
|
||||||
_mgr.processConvertPrivate(tok.nextToken(), out);
|
|
||||||
else
|
|
||||||
_mgr.error("Usage: convertprivate <privateData>", out);
|
|
||||||
} else if ("close".equalsIgnoreCase(cmd)) {
|
|
||||||
if (tok.hasMoreTokens()) {
|
|
||||||
String closeArg;
|
|
||||||
if ((closeArg = tok.nextToken()).equals("forced")) {
|
|
||||||
if (tok.hasMoreTokens()) {
|
|
||||||
_mgr.processClose(tok.nextToken(), true, out);
|
|
||||||
} else {
|
|
||||||
_mgr.error("Usage: close [forced] <jobnumber>|all", out);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_mgr.processClose(closeArg, false, out);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_mgr.error("Usage: close [forced] <jobnumber>|all", out);
|
|
||||||
}
|
|
||||||
} else if ("genkey".equalsIgnoreCase(cmd)) {
|
|
||||||
_mgr.processGenKey(out);
|
|
||||||
} else if ("list".equalsIgnoreCase(cmd)) {
|
|
||||||
_mgr.processList(out);
|
|
||||||
} else if ("listen_on".equalsIgnoreCase(cmd)) {
|
|
||||||
if (tok.hasMoreTokens()) {
|
|
||||||
_mgr.processListenOn(tok.nextToken(), out);
|
|
||||||
} else {
|
|
||||||
_mgr.error("Usage: listen_on <ip>", out);
|
|
||||||
}
|
|
||||||
} else if ("openclient".equalsIgnoreCase(cmd)) {
|
|
||||||
int listenPort = 0;
|
|
||||||
String peer = null;
|
|
||||||
String sharedClient = null;
|
|
||||||
int numTokens = tok.countTokens();
|
|
||||||
if (numTokens < 2 || numTokens > 3) {
|
|
||||||
_mgr.error("Usage: openclient <listenPort> <peer> <sharedClient>", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
listenPort = Integer.parseInt(tok.nextToken());
|
|
||||||
peer = tok.nextToken();
|
|
||||||
if (tok.hasMoreTokens())
|
|
||||||
sharedClient = tok.nextToken();
|
|
||||||
else
|
|
||||||
sharedClient = "true";
|
|
||||||
_mgr.processOpenClient(listenPort, peer, sharedClient, out);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
_mgr.error("Bad listen port", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if ("openhttpclient".equalsIgnoreCase(cmd)) {
|
|
||||||
int listenPort = 0;
|
|
||||||
String proxy = "squid.i2p";
|
|
||||||
String sharedClient = "true";
|
|
||||||
int numTokens = tok.countTokens();
|
|
||||||
if (numTokens < 1 || numTokens > 3) {
|
|
||||||
_mgr.error("Usage: openhttpclient <listenPort> [<sharedClient>] [<proxy>]", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
listenPort = Integer.parseInt(tok.nextToken());
|
|
||||||
if (tok.hasMoreTokens()) {
|
|
||||||
String val = tok.nextToken();
|
|
||||||
if (tok.hasMoreTokens()) {
|
|
||||||
sharedClient = val;
|
|
||||||
proxy = tok.nextToken();
|
|
||||||
} else {
|
|
||||||
if ( ("true".equals(val)) || ("false".equals(val)) ) {
|
|
||||||
sharedClient = val;
|
|
||||||
} else {
|
|
||||||
proxy = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_mgr.processOpenHTTPClient(listenPort, sharedClient, proxy, out);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
_mgr.error("Bad listen port", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if ("opensockstunnel".equalsIgnoreCase(cmd)) {
|
|
||||||
int listenPort = 0;
|
|
||||||
if (!tok.hasMoreTokens()) {
|
|
||||||
_mgr.error("Usage: opensockstunnel <listenPort>", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
String portStr = tok.nextToken();
|
|
||||||
listenPort = Integer.parseInt(portStr);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
_mgr.error("Bad listen port", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tok.hasMoreTokens()) {
|
|
||||||
_mgr.error("Usage: opensockstunnel <listenport>", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_mgr.processOpenSOCKSTunnel(listenPort, out);
|
|
||||||
} else if ("openserver".equalsIgnoreCase(cmd)) {
|
|
||||||
int listenPort = 0;
|
|
||||||
String serverHost = null;
|
|
||||||
String serverKeys = null;
|
|
||||||
if (!tok.hasMoreTokens()) {
|
|
||||||
_mgr.error("Usage: openserver <serverHost> <serverPort> <serverKeys>", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
serverHost = tok.nextToken();
|
|
||||||
|
|
||||||
if (!tok.hasMoreTokens()) {
|
|
||||||
_mgr.error("Usage: openserver <serverHost> <serverPort> <serverKeys>", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
String portStr = tok.nextToken();
|
|
||||||
listenPort = Integer.parseInt(portStr);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
_mgr.error("Bad listen port", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!tok.hasMoreTokens()) {
|
|
||||||
_mgr.error("Usage: openserver <serverHost> <serverPort> <serverKeys>", out);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
serverKeys = tok.nextToken();
|
|
||||||
_mgr.processOpenServer(serverHost, listenPort, serverKeys, out);
|
|
||||||
} else {
|
|
||||||
_mgr.unknownCommand(command, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,7 +28,8 @@ public class ConfigNetHandler extends FormHandler {
|
|||||||
private boolean _reseedRequested;
|
private boolean _reseedRequested;
|
||||||
private boolean _saveRequested;
|
private boolean _saveRequested;
|
||||||
private boolean _timeSyncEnabled;
|
private boolean _timeSyncEnabled;
|
||||||
private String _port;
|
private String _tcpPort;
|
||||||
|
private String _udpPort;
|
||||||
private String _inboundRate;
|
private String _inboundRate;
|
||||||
private String _inboundBurst;
|
private String _inboundBurst;
|
||||||
private String _outboundRate;
|
private String _outboundRate;
|
||||||
@ -56,8 +57,11 @@ public class ConfigNetHandler extends FormHandler {
|
|||||||
public void setHostname(String hostname) {
|
public void setHostname(String hostname) {
|
||||||
_hostname = (hostname != null ? hostname.trim() : null);
|
_hostname = (hostname != null ? hostname.trim() : null);
|
||||||
}
|
}
|
||||||
public void setPort(String port) {
|
public void setTcpPort(String port) {
|
||||||
_port = (port != null ? port.trim() : null);
|
_tcpPort = (port != null ? port.trim() : null);
|
||||||
|
}
|
||||||
|
public void setUdpPort(String port) {
|
||||||
|
_udpPort = (port != null ? port.trim() : null);
|
||||||
}
|
}
|
||||||
public void setInboundrate(String rate) {
|
public void setInboundrate(String rate) {
|
||||||
_inboundRate = (rate != null ? rate.trim() : null);
|
_inboundRate = (rate != null ? rate.trim() : null);
|
||||||
@ -207,14 +211,25 @@ public class ConfigNetHandler extends FormHandler {
|
|||||||
restartRequired = true;
|
restartRequired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( (_port != null) && (_port.length() > 0) ) {
|
if ( (_tcpPort != null) && (_tcpPort.length() > 0) ) {
|
||||||
String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT);
|
String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT);
|
||||||
if ( (oldPort == null) && (_port.equals("8887")) ) {
|
if ( (oldPort == null) && (_tcpPort.equals("8887")) ) {
|
||||||
// still on default.. noop
|
// still on default.. noop
|
||||||
} else if ( (oldPort == null) || (!oldPort.equalsIgnoreCase(_port)) ) {
|
} else if ( (oldPort == null) || (!oldPort.equalsIgnoreCase(_tcpPort)) ) {
|
||||||
// its not the default OR it has changed
|
// its not the default OR it has changed
|
||||||
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT, _port);
|
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT, _tcpPort);
|
||||||
addFormNotice("Updating TCP port from " + oldPort + " to " + _port);
|
addFormNotice("Updating TCP port from " + oldPort + " to " + _tcpPort);
|
||||||
|
restartRequired = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( (_udpPort != null) && (_udpPort.length() > 0) ) {
|
||||||
|
String oldPort = _context.router().getConfigSetting(ConfigNetHelper.PROP_I2NP_UDP_PORT);
|
||||||
|
if ( (oldPort == null) && (_udpPort.equals("8887")) ) {
|
||||||
|
// still on default.. noop
|
||||||
|
} else if ( (oldPort == null) || (!oldPort.equalsIgnoreCase(_udpPort)) ) {
|
||||||
|
// its not the default OR it has changed
|
||||||
|
_context.router().setConfigSetting(ConfigNetHelper.PROP_I2NP_TCP_PORT, _udpPort);
|
||||||
|
addFormNotice("Updating UDP port from " + oldPort + " to " + _udpPort);
|
||||||
restartRequired = true;
|
restartRequired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,13 @@ public class ConfigNetHelper {
|
|||||||
/** copied from various private TCP components */
|
/** copied from various private TCP components */
|
||||||
public final static String PROP_I2NP_TCP_HOSTNAME = "i2np.tcp.hostname";
|
public final static String PROP_I2NP_TCP_HOSTNAME = "i2np.tcp.hostname";
|
||||||
public final static String PROP_I2NP_TCP_PORT = "i2np.tcp.port";
|
public final static String PROP_I2NP_TCP_PORT = "i2np.tcp.port";
|
||||||
|
public final static String PROP_I2NP_UDP_PORT = "i2np.udp.port";
|
||||||
|
public final static String PROP_I2NP_INTERNAL_UDP_PORT = "i2np.udp.internalPort";
|
||||||
|
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return _context.getProperty(PROP_I2NP_TCP_HOSTNAME);
|
return _context.getProperty(PROP_I2NP_TCP_HOSTNAME);
|
||||||
}
|
}
|
||||||
public String getPort() {
|
public String getTcpPort() {
|
||||||
int port = 8887;
|
int port = 8887;
|
||||||
String val = _context.getProperty(PROP_I2NP_TCP_PORT);
|
String val = _context.getProperty(PROP_I2NP_TCP_PORT);
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
@ -41,6 +43,21 @@ public class ConfigNetHelper {
|
|||||||
return "" + port;
|
return "" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUdpPort() {
|
||||||
|
int port = 8887;
|
||||||
|
String val = _context.getProperty(PROP_I2NP_UDP_PORT);
|
||||||
|
if (val == null)
|
||||||
|
val = _context.getProperty(PROP_I2NP_INTERNAL_UDP_PORT);
|
||||||
|
if (val != null) {
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(val);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
// ignore, use default from above
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "" + port;
|
||||||
|
}
|
||||||
|
|
||||||
public String getEnableTimeSyncChecked() {
|
public String getEnableTimeSyncChecked() {
|
||||||
String disabled = _context.getProperty(Timestamper.PROP_DISABLED, "false");
|
String disabled = _context.getProperty(Timestamper.PROP_DISABLED, "false");
|
||||||
if ( (disabled != null) && ("true".equalsIgnoreCase(disabled)) )
|
if ( (disabled != null) && ("true".equalsIgnoreCase(disabled)) )
|
||||||
|
@ -6,6 +6,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import net.i2p.util.Log;
|
||||||
import net.i2p.stat.StatManager;
|
import net.i2p.stat.StatManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,6 +23,7 @@ public class ConfigStatsHandler extends FormHandler {
|
|||||||
public ConfigStatsHandler() {
|
public ConfigStatsHandler() {
|
||||||
super();
|
super();
|
||||||
_stats = new ArrayList();
|
_stats = new ArrayList();
|
||||||
|
_explicitFilter = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processForm() {
|
protected void processForm() {
|
||||||
@ -36,27 +38,14 @@ public class ConfigStatsHandler extends FormHandler {
|
|||||||
if (stats != null) {
|
if (stats != null) {
|
||||||
for (int i = 0; i < stats.length; i++) {
|
for (int i = 0; i < stats.length; i++) {
|
||||||
String cur = stats[i].trim();
|
String cur = stats[i].trim();
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Stat: [" + cur + "]");
|
||||||
if ( (cur.length() > 0) && (!_stats.contains(cur)) )
|
if ( (cur.length() > 0) && (!_stats.contains(cur)) )
|
||||||
_stats.add(cur);
|
_stats.add(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Updated stats: " + _stats);
|
||||||
public void setStatList(String stat) {
|
|
||||||
if (stat != null) {
|
|
||||||
if (stat.indexOf(',') != -1) {
|
|
||||||
StringTokenizer tok = new StringTokenizer(stat, ",");
|
|
||||||
while (tok.hasMoreTokens()) {
|
|
||||||
String cur = tok.nextToken().trim();
|
|
||||||
if ( (cur.length() > 0) && (!_stats.contains(cur)) )
|
|
||||||
_stats.add(cur);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stat = stat.trim();
|
|
||||||
if ( (stat.length() > 0) && (!_stats.contains(stat)) )
|
|
||||||
_stats.add(stat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExplicitFilter(String foo) { _explicitFilter = true; }
|
public void setExplicitFilter(String foo) { _explicitFilter = true; }
|
||||||
@ -74,7 +63,19 @@ public class ConfigStatsHandler extends FormHandler {
|
|||||||
|
|
||||||
if (_explicitFilter) {
|
if (_explicitFilter) {
|
||||||
_stats.clear();
|
_stats.clear();
|
||||||
setStatList(_explicitFilterValue);
|
|
||||||
|
if (_explicitFilterValue.indexOf(',') != -1) {
|
||||||
|
StringTokenizer tok = new StringTokenizer(_explicitFilterValue, ",");
|
||||||
|
while (tok.hasMoreTokens()) {
|
||||||
|
String cur = tok.nextToken().trim();
|
||||||
|
if ( (cur.length() > 0) && (!_stats.contains(cur)) )
|
||||||
|
_stats.add(cur);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String stat = _explicitFilterValue.trim();
|
||||||
|
if ( (stat.length() > 0) && (!_stats.contains(stat)) )
|
||||||
|
_stats.add(stat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer stats = new StringBuffer();
|
StringBuffer stats = new StringBuffer();
|
||||||
|
@ -4,6 +4,7 @@ import java.util.List;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple form handler base class - does not depend on servlets or jsp,
|
* Simple form handler base class - does not depend on servlets or jsp,
|
||||||
@ -16,6 +17,7 @@ import net.i2p.router.RouterContext;
|
|||||||
*/
|
*/
|
||||||
public class FormHandler {
|
public class FormHandler {
|
||||||
protected RouterContext _context;
|
protected RouterContext _context;
|
||||||
|
protected Log _log;
|
||||||
private String _nonce;
|
private String _nonce;
|
||||||
protected String _action;
|
protected String _action;
|
||||||
private List _errors;
|
private List _errors;
|
||||||
@ -41,6 +43,7 @@ public class FormHandler {
|
|||||||
public void setContextId(String contextId) {
|
public void setContextId(String contextId) {
|
||||||
try {
|
try {
|
||||||
_context = ContextHelper.getContext(contextId);
|
_context = ContextHelper.getContext(contextId);
|
||||||
|
_log = _context.logManager().getLog(getClass());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,13 @@
|
|||||||
<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" />
|
||||||
|
|
||||||
TCP port:
|
UDP port: <i><jsp:getProperty name="nethelper" property="udpPort" /></i><br />
|
||||||
<input name="port" type="text" size="4" value="<jsp:getProperty name="nethelper" property="port" />" /> <br />
|
<!-- <input name="udpPort" type="text" size="5" value="<jsp:getProperty name="nethelper" property="udpPort" />" /><br /> -->
|
||||||
|
<b>You must poke a hole in your firewall or NAT (if applicable) to receive new inbound UDP packets on
|
||||||
|
this port from arbitrary peers (this requirement will be removed in i2p 0.6.1, but is necessary now)</b><br />
|
||||||
|
TCP port: <input name="tcpPort" type="text" size="5" value="<jsp:getProperty name="nethelper" property="tcpPort" />" /> <br />
|
||||||
<b>You must poke a hole in your firewall or NAT (if applicable) so that you can receive inbound TCP
|
<b>You must poke a hole in your firewall or NAT (if applicable) so that you can receive inbound TCP
|
||||||
connections on it.</b> Nothing will work if you don't. Sorry. We know how to make it so
|
connections on it (this requirement will be removed in i2p 0.6.1, but is necessary now)</b>
|
||||||
this restriction won't be necessary, but its later on in the
|
|
||||||
<a href="http://www.i2p.net/roadmap">roadmap</a> and we only have so many coder-hours (but if you want
|
|
||||||
to help, please <a href="http://www.i2p.net/getinvolved">get involved!</a>)
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<b>Bandwidth limiter</b><br />
|
<b>Bandwidth limiter</b><br />
|
||||||
@ -57,7 +57,7 @@
|
|||||||
packets on port 123 to one of the pool.ntp.org machines (or some other SNTP server).</i>
|
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 TCP port will force a 'soft restart' - dropping your connections and clients as
|
<i>Changing the TCP or UDP port will force a 'soft restart' - dropping your connections 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>
|
||||||
@ -73,6 +73,13 @@
|
|||||||
"i2p.reseedURL=someURL" (e.g. java -Di2p.reseedURL=http://dev.i2p.net/i2pdb/ ...). You can
|
"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,
|
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>
|
whatever) and saving them to your netDb/ directory.</p>
|
||||||
|
<p>
|
||||||
|
With the SSU transport, the internal UDP port may be different from the external
|
||||||
|
UDP port (in case of a firewall/NAT) - the UDP port field above specifies the
|
||||||
|
external one and assumes they are the same, but if you want to set the internal
|
||||||
|
port to something else, you can add "i2np.udp.internalPort=1234" to the
|
||||||
|
<a href="configadvanced.jsp">advanced</a> config and restart the router.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -33,7 +33,7 @@ public class ConnectionPacketHandler {
|
|||||||
boolean ok = verifyPacket(packet, con);
|
boolean ok = verifyPacket(packet, con);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
if ( (!packet.isFlagSet(Packet.FLAG_RESET)) && (_log.shouldLog(Log.ERROR)) )
|
if ( (!packet.isFlagSet(Packet.FLAG_RESET)) && (_log.shouldLog(Log.ERROR)) )
|
||||||
_log.error("Packet does NOT verify: " + packet);
|
_log.error("Packet does NOT verify: " + packet + " on " + con);
|
||||||
packet.releasePayload();
|
packet.releasePayload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -305,16 +305,16 @@ public class ConnectionPacketHandler {
|
|||||||
if (packet.getSequenceNum() <= 2) {
|
if (packet.getSequenceNum() <= 2) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.warn("Packet without RST or SYN where we dont know stream ID: "
|
_log.error("Packet without RST or SYN where we dont know stream ID: "
|
||||||
+ packet);
|
+ packet);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!DataHelper.eq(con.getSendStreamId(), packet.getReceiveStreamId())) {
|
if (!DataHelper.eq(con.getSendStreamId(), packet.getReceiveStreamId())) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.warn("Packet received with the wrong reply stream id: "
|
_log.error("Packet received with the wrong reply stream id: "
|
||||||
+ con + " / " + packet);
|
+ con + " / " + packet);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -331,8 +331,8 @@ public class ConnectionPacketHandler {
|
|||||||
if (DataHelper.eq(con.getReceiveStreamId(), packet.getSendStreamId())) {
|
if (DataHelper.eq(con.getReceiveStreamId(), packet.getSendStreamId())) {
|
||||||
boolean ok = packet.verifySignature(_context, packet.getOptionalFrom(), null);
|
boolean ok = packet.verifySignature(_context, packet.getOptionalFrom(), null);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.warn("Received unsigned / forged RST on " + con);
|
_log.error("Received unsigned / forged RST on " + con);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
@ -14,8 +14,8 @@ package net.i2p;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CoreVersion {
|
public class CoreVersion {
|
||||||
public final static String ID = "$Revision: 1.34 $ $Date: 2005/04/06 10:43:26 $";
|
public final static String ID = "$Revision: 1.35 $ $Date: 2005/04/20 15:14:20 $";
|
||||||
public final static String VERSION = "0.5.0.7";
|
public final static String VERSION = "0.6";
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Core version: " + VERSION);
|
System.out.println("I2P Core version: " + VERSION);
|
||||||
|
@ -121,7 +121,7 @@ class I2CPMessageProducer {
|
|||||||
* garlic crypto added by the router)
|
* garlic crypto added by the router)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static final boolean END_TO_END_CRYPTO = true;
|
static final boolean END_TO_END_CRYPTO = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new signed payload and send it off to the destination
|
* Create a new signed payload and send it off to the destination
|
||||||
|
@ -260,7 +260,10 @@ public class DHSessionKeyBuilder {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public byte[] getMyPublicValueBytes() {
|
public byte[] getMyPublicValueBytes() {
|
||||||
BigInteger bi = getMyPublicValue();
|
return toByteArray(getMyPublicValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final byte[] toByteArray(BigInteger bi) {
|
||||||
byte data[] = bi.toByteArray();
|
byte data[] = bi.toByteArray();
|
||||||
byte rv[] = new byte[256];
|
byte rv[] = new byte[256];
|
||||||
if (data.length == 257) // high byte has the sign bit
|
if (data.length == 257) // high byte has the sign bit
|
||||||
@ -299,6 +302,9 @@ public class DHSessionKeyBuilder {
|
|||||||
public BigInteger getPeerPublicValue() {
|
public BigInteger getPeerPublicValue() {
|
||||||
return _peerValue;
|
return _peerValue;
|
||||||
}
|
}
|
||||||
|
public byte[] getPeerPublicValueBytes() {
|
||||||
|
return toByteArray(getPeerPublicValue());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the session key, calculating it if necessary (and if possible).
|
* Retrieve the session key, calculating it if necessary (and if possible).
|
||||||
|
@ -25,9 +25,13 @@ public class DHSessionKeyBuilderTest extends TestCase {
|
|||||||
DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder();
|
DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder();
|
||||||
DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder();
|
DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder();
|
||||||
BigInteger pub1 = builder1.getMyPublicValue();
|
BigInteger pub1 = builder1.getMyPublicValue();
|
||||||
builder2.setPeerPublicValue(pub1);
|
|
||||||
BigInteger pub2 = builder2.getMyPublicValue();
|
BigInteger pub2 = builder2.getMyPublicValue();
|
||||||
builder1.setPeerPublicValue(pub2);
|
try {
|
||||||
|
builder2.setPeerPublicValue(pub1);
|
||||||
|
builder1.setPeerPublicValue(pub2);
|
||||||
|
} catch (DHSessionKeyBuilder.InvalidPublicParameterException ippe) {
|
||||||
|
assertTrue(ippe.getMessage(), true);
|
||||||
|
}
|
||||||
SessionKey key1 = builder1.getSessionKey();
|
SessionKey key1 = builder1.getSessionKey();
|
||||||
SessionKey key2 = builder2.getSessionKey();
|
SessionKey key2 = builder2.getSessionKey();
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ import net.i2p.util.Log;
|
|||||||
public class MessagePayloadMessageTest extends StructureTest {
|
public class MessagePayloadMessageTest extends StructureTest {
|
||||||
public DataStructure createDataStructure() throws DataFormatException {
|
public DataStructure createDataStructure() throws DataFormatException {
|
||||||
MessagePayloadMessage msg = new MessagePayloadMessage();
|
MessagePayloadMessage msg = new MessagePayloadMessage();
|
||||||
msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure());
|
msg.setMessageId(123);
|
||||||
msg.setPayload((Payload)(new PayloadTest()).createDataStructure());
|
msg.setPayload((Payload)(new PayloadTest()).createDataStructure());
|
||||||
msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure());
|
msg.setSessionId(321);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
public DataStructure createStructureToRead() { return new MessagePayloadMessage(); }
|
public DataStructure createStructureToRead() { return new MessagePayloadMessage(); }
|
||||||
|
@ -22,8 +22,8 @@ import net.i2p.data.i2cp.SessionId;
|
|||||||
public class MessageStatusMessageTest extends StructureTest {
|
public class MessageStatusMessageTest extends StructureTest {
|
||||||
public DataStructure createDataStructure() throws DataFormatException {
|
public DataStructure createDataStructure() throws DataFormatException {
|
||||||
MessageStatusMessage msg = new MessageStatusMessage();
|
MessageStatusMessage msg = new MessageStatusMessage();
|
||||||
msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure());
|
msg.setSessionId(42);
|
||||||
msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure());
|
msg.setMessageId(41);
|
||||||
msg.setSize(1024*1024*42L);
|
msg.setSize(1024*1024*42L);
|
||||||
msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE);
|
msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE);
|
||||||
msg.setNonce(1);
|
msg.setNonce(1);
|
||||||
|
@ -22,8 +22,8 @@ import net.i2p.data.i2cp.SessionId;
|
|||||||
public class ReceiveMessageBeginMessageTest extends StructureTest {
|
public class ReceiveMessageBeginMessageTest extends StructureTest {
|
||||||
public DataStructure createDataStructure() throws DataFormatException {
|
public DataStructure createDataStructure() throws DataFormatException {
|
||||||
ReceiveMessageBeginMessage msg = new ReceiveMessageBeginMessage();
|
ReceiveMessageBeginMessage msg = new ReceiveMessageBeginMessage();
|
||||||
msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure());
|
msg.setSessionId(321);
|
||||||
msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure());
|
msg.setMessageId(123);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
public DataStructure createStructureToRead() { return new ReceiveMessageBeginMessage(); }
|
public DataStructure createStructureToRead() { return new ReceiveMessageBeginMessage(); }
|
||||||
|
@ -22,8 +22,8 @@ import net.i2p.data.i2cp.SessionId;
|
|||||||
public class ReceiveMessageEndMessageTest extends StructureTest {
|
public class ReceiveMessageEndMessageTest extends StructureTest {
|
||||||
public DataStructure createDataStructure() throws DataFormatException {
|
public DataStructure createDataStructure() throws DataFormatException {
|
||||||
ReceiveMessageEndMessage msg = new ReceiveMessageEndMessage();
|
ReceiveMessageEndMessage msg = new ReceiveMessageEndMessage();
|
||||||
msg.setSessionId((SessionId)(new SessionIdTest()).createDataStructure());
|
msg.setSessionId(321);
|
||||||
msg.setMessageId((MessageId)(new MessageIdTest()).createDataStructure());
|
msg.setMessageId(123);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
public DataStructure createStructureToRead() { return new ReceiveMessageEndMessage(); }
|
public DataStructure createStructureToRead() { return new ReceiveMessageEndMessage(); }
|
||||||
|
21
history.txt
21
history.txt
@ -1,4 +1,23 @@
|
|||||||
$Id: history.txt,v 1.216 2005/07/21 17:37:16 jrandom Exp $
|
$Id: history.txt,v 1.217 2005/07/22 19:15:59 jrandom Exp $
|
||||||
|
|
||||||
|
* 2005-07-27 0.6 released
|
||||||
|
|
||||||
|
2005-07-27 jrandom
|
||||||
|
* Enabled SSU as the default top priority transport, adjusting the
|
||||||
|
config.jsp page accordingly.
|
||||||
|
* Add verification fields to the SSU and TCP connection negotiation (not
|
||||||
|
compatible with previous builds)
|
||||||
|
* Enable the backwards incompatible tunnel crypto change as documented in
|
||||||
|
tunnel-alt.html (have each hop encrypt the received IV before using it,
|
||||||
|
then encrypt it again before sending it on)
|
||||||
|
* Disable the I2CP encryption, leaving in place the end to end garlic
|
||||||
|
encryption (another backwards incompatible change)
|
||||||
|
* Adjust the protocol versions on the TCP and SSU transports so that they
|
||||||
|
won't talk to older routers.
|
||||||
|
* Fix up the config stats handling again
|
||||||
|
* Fix a rare off-by-one in the SSU fragmentation
|
||||||
|
* Reduce some unnecessary netDb resending by inluding the peers queried
|
||||||
|
successfully in the store redundancy count.
|
||||||
|
|
||||||
2005-07-22 jrandom
|
2005-07-22 jrandom
|
||||||
* Use the small thread pool for I2PTunnelHTTPServer (already used for
|
* Use the small thread pool for I2PTunnelHTTPServer (already used for
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<i2p.news date="$Date: 2005/04/06 10:43:25 $">
|
<i2p.news date="$Date: 2005/04/20 15:14:18 $">
|
||||||
<i2p.release version="0.5.0.7" date="2005/04/20" minVersion="0.5.0.4"
|
<i2p.release version="0.6" date="2005/07/27" minVersion="0.6"
|
||||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
|
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"
|
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/April-2005/000709.html"
|
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/April-2005/000709.html"
|
||||||
publicannouncement="http://dev.i2p.net/pipermail/i2p/April-2005/000709.html" />
|
publicannouncement="http://dev.i2p.net/pipermail/i2p/April-2005/000709.html" />
|
||||||
<i2p.notes date="2005/04/19"
|
<i2p.notes date="2005/07/26"
|
||||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/April-2005/000708.html"
|
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-July/000823.html"
|
||||||
publicurl="http://dev.i2p.net/pipermail/i2p/April-2005/000708.html"
|
publicurl="http://dev.i2p.net/pipermail/i2p/2005-July/000823.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/meeting138"
|
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/meeting138"
|
||||||
publiclogs="http://www.i2p.net/meeting138" />
|
publiclogs="http://www.i2p.net/meeting138" />
|
||||||
<h1>Congratulations on getting I2P installed!</h1>
|
<h1>Congratulations on getting I2P installed!</h1>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<info>
|
<info>
|
||||||
<appname>i2p</appname>
|
<appname>i2p</appname>
|
||||||
<appversion>0.5.0.7</appversion>
|
<appversion>0.6</appversion>
|
||||||
<authors>
|
<authors>
|
||||||
<author name="I2P" email="support@i2p.net"/>
|
<author name="I2P" email="support@i2p.net"/>
|
||||||
</authors>
|
</authors>
|
||||||
|
15
news.xml
15
news.xml
@ -1,20 +1,15 @@
|
|||||||
<i2p.news date="$Date: 2005/07/11 22:56:42 $">
|
<i2p.news date="$Date: 2005/07/13 16:59:01 $">
|
||||||
<i2p.release version="0.5.0.7" date="2005/04/20" minVersion="0.5.0.4"
|
<i2p.release version="0.7" date="2005/07/27" minVersion="0.6"
|
||||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/i2pupdate.sud"
|
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"
|
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-April/000709.html"
|
anonannouncement="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-April/000709.html"
|
||||||
publicannouncement="http://dev.i2p.net/pipermail/i2p/2005-April/000709.html" />
|
publicannouncement="http://dev.i2p.net/pipermail/i2p/2005-April/000709.html" />
|
||||||
<i2p.notes date="2005/04/19"
|
<i2p.notes date="2005/04/19"
|
||||||
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-April/000723.html"
|
anonurl="http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/pipermail/i2p/2005-July/000823.html"
|
||||||
publicurl="http://dev.i2p.net/pipermail/i2p/2005-April/000723.html"
|
publicurl="http://dev.i2p.net/pipermail/i2p/2005-July/000823.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/meeting139"
|
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/meeting139"
|
||||||
publiclogs="http://www.i2p.net/meeting138" />
|
publiclogs="http://www.i2p.net/meeting138" />
|
||||||
Thanks to those helping out with the SSU test - there have been lots
|
Welcome to the new 0.6 series of releases, using the new SSU transport!
|
||||||
of updates lately, so upgrading to the latest CVS HEAD (currently
|
|
||||||
0.5.0.7-14 as of 2005/07/13) would be worthwhile, and the archived
|
|
||||||
i2pupdate.zip mentioned
|
|
||||||
<a href="http://dev.i2p.net/~jrandom/ssu_test.txt">before</a>
|
|
||||||
may not always be up to date.
|
|
||||||
<br />
|
<br />
|
||||||
</i2p.news>
|
</i2p.news>
|
||||||
|
|
||||||
|
@ -15,11 +15,10 @@ listed (if not, <a href="#trouble">see below</a>). Once those are up, you can:<
|
|||||||
<li><a href="http://duck.i2p/">duck.i2p</a>: duck's eepsite, with links to other active sites</li>
|
<li><a href="http://duck.i2p/">duck.i2p</a>: duck's eepsite, with links to other active sites</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://ugha.i2p/">ugha.i2p</a>: ugha's eepsite, a wiki that anyone can edit, and lots of links</li>
|
||||||
<li><a href="http://orion.i2p/">orion.i2p</a>: a site which tracks eepsite uptime and changes</li>
|
<li><a href="http://orion.i2p/">orion.i2p</a>: a site which tracks eepsite uptime and changes</li>
|
||||||
<li><a href="http://files.i2p/">files.i2p</a>: a search engine that tries to keep track of things on I2P</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://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.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://dev.i2p/">dev.i2p</a>: a secure and anonymous connection to <a href="http://dev.i2p.net/">dev.i2p.net</a></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 proxies: <a href="http://fproxy.i2p/">fproxy.i2p</a> and <a href="http://freenet.eco.i2p/">freenet.eco.i2p</a></li>
|
<li>Freenet proxies: <a href="http://fproxy.i2p/">fproxy.i2p</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
There are many more eepsites - just follow the links from the ones you see,
|
There are many more eepsites - just follow the links from the ones you see,
|
||||||
bookmark your favorites, and visit them often!</li>
|
bookmark your favorites, and visit them often!</li>
|
||||||
@ -56,7 +55,7 @@ IRC (be sure to split it into two lines, as its too long for one).</p>
|
|||||||
|
|
||||||
<p>If the left hand side has a warning, telling you to check your NAT or firewall, please
|
<p>If the left hand side has a warning, telling you to check your NAT or firewall, please
|
||||||
see the <a href="/config.jsp">config page</a> and make sure that you can receive <b>inbound
|
see the <a href="/config.jsp">config page</a> and make sure that you can receive <b>inbound
|
||||||
TCP connections on port 8887</b> (or another port that you specify). Problems forwarding
|
TCP and UDP connections on port 8887</b> (or another port that you specify). Problems forwarding
|
||||||
that port account for the vast majority of issues people run into. When it says
|
that port account for the vast majority of issues people run into. When it says
|
||||||
"Active: 72/85", the "72" means how many peers you are connected with now, and "85" means
|
"Active: 72/85", the "72" means how many peers you are connected with now, and "85" means
|
||||||
how many you have spoken with recently - if that first number is 0, you can bet that there
|
how many you have spoken with recently - if that first number is 0, you can bet that there
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<code>$Id: tunnel-alt.html,v 1.7 2005/02/16 19:48:18 jrandom Exp $</code>
|
<code>$Id: tunnel-alt.html,v 1.8 2005/07/07 16:16:57 jrandom Exp $</code>
|
||||||
<pre>
|
<pre>
|
||||||
1) <a href="#tunnel.overview">Tunnel overview</a>
|
1) <a href="#tunnel.overview">Tunnel overview</a>
|
||||||
2) <a href="#tunnel.operation">Tunnel operation</a>
|
2) <a href="#tunnel.operation">Tunnel operation</a>
|
||||||
@ -173,9 +173,12 @@ the initial preprocessed data.</p>
|
|||||||
the same previous hop as before (initialized when the first message comes through
|
the same previous hop as before (initialized when the first message comes through
|
||||||
the tunnel). If the previous peer is a different router, or if the message has
|
the tunnel). If the previous peer is a different router, or if the message has
|
||||||
already been seen, the message is dropped. The participant then encrypts the
|
already been seen, the message is dropped. The participant then encrypts the
|
||||||
data with AES256/CBC using the participant's layer key and the received IV,
|
received IV with AES256/ECB using their IV key to determine the current IV, uses
|
||||||
updates the IV by encrypting it with AES256/ECB using the participant's IV key,
|
that IV with the participant's layer key to encrypt the data, encrypts the
|
||||||
then forwards the tuple {nextTunnelId, nextIV, encryptedData} to the next hop.</p>
|
current IV with AES256/ECB using their IV key again, then forwards the tuple
|
||||||
|
{nextTunnelId, nextIV, encryptedData} to the next hop. This double encryption
|
||||||
|
of the IV (both before and after use) help address a certain class of
|
||||||
|
confirmation attacks.</p>
|
||||||
|
|
||||||
<p>Duplicate message detection is handled by a decaying Bloom filter on message
|
<p>Duplicate message detection is handled by a decaying Bloom filter on message
|
||||||
IVs. Each router maintains a single Bloom filter to contain the XOR of the IV and
|
IVs. Each router maintains a single Bloom filter to contain the XOR of the IV and
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<code>$Id: udp.html,v 1.12 2005/04/09 18:15:53 jrandom Exp $</code>
|
<code>$Id: udp.html,v 1.13 2005/05/01 15:08:08 jrandom Exp $</code>
|
||||||
|
|
||||||
<h1>Secure Semireliable UDP (SSU)</h1>
|
<h1>Secure Semireliable UDP (SSU)</h1>
|
||||||
<b>DRAFT</b>
|
<b>DRAFT</b>
|
||||||
@ -141,7 +141,7 @@ around briefly, to address packet loss and reordering.</p>
|
|||||||
<li>4 byte timestamp (seconds from the epoch) for use in the DSA
|
<li>4 byte timestamp (seconds from the epoch) for use in the DSA
|
||||||
signature</li>
|
signature</li>
|
||||||
<li>40 byte DSA signature of the critical exchanged data
|
<li>40 byte DSA signature of the critical exchanged data
|
||||||
(Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's
|
(X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port + Alice's
|
||||||
new relay tag + Bob's signed on time), encrypted with another
|
new relay tag + Bob's signed on time), encrypted with another
|
||||||
layer of encryption using the negotiated sessionKey. The IV
|
layer of encryption using the negotiated sessionKey. The IV
|
||||||
is reused here.</li>
|
is reused here.</li>
|
||||||
@ -197,7 +197,7 @@ bits 4-7: total identity fragments</pre></li>
|
|||||||
<li>on the last identity fragment, the signed on time is
|
<li>on the last identity fragment, the signed on time is
|
||||||
included after the identity fragment, and the last 40
|
included after the identity fragment, and the last 40
|
||||||
bytes contain the DSA signature of the critical exchanged
|
bytes contain the DSA signature of the critical exchanged
|
||||||
data (Alice's IP + Alice's port + Bob's IP + Bob's port
|
data (X + Y + Alice's IP + Alice's port + Bob's IP + Bob's port
|
||||||
+ Alice's new relay key + Alice's signed on time)</li>
|
+ Alice's new relay key + Alice's signed on time)</li>
|
||||||
</ul></td></tr>
|
</ul></td></tr>
|
||||||
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
<tr><td align="right" valign="top"><b>Key used:</b></td>
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.207 $ $Date: 2005/07/21 17:37:15 $";
|
public final static String ID = "$Revision: 1.208 $ $Date: 2005/07/22 19:15:58 $";
|
||||||
public final static String VERSION = "0.5.0.7";
|
public final static String VERSION = "0.6";
|
||||||
public final static long BUILD = 19;
|
public final static long BUILD = 0;
|
||||||
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);
|
||||||
|
@ -102,12 +102,12 @@ public class StatisticsManager implements Service {
|
|||||||
stats.putAll(_context.profileManager().summarizePeers(_publishedStats));
|
stats.putAll(_context.profileManager().summarizePeers(_publishedStats));
|
||||||
|
|
||||||
includeThroughput(stats);
|
includeThroughput(stats);
|
||||||
includeRate("router.invalidMessageTime", stats, new long[] { 10*60*1000 });
|
//includeRate("router.invalidMessageTime", stats, new long[] { 10*60*1000 });
|
||||||
includeRate("router.duplicateMessageId", stats, new long[] { 24*60*60*1000 });
|
includeRate("router.duplicateMessageId", stats, new long[] { 24*60*60*1000 });
|
||||||
includeRate("tunnel.duplicateIV", stats, new long[] { 24*60*60*1000 });
|
//includeRate("tunnel.duplicateIV", stats, new long[] { 24*60*60*1000 });
|
||||||
includeRate("tunnel.fragmentedDropped", stats, new long[] { 10*60*1000, 3*60*60*1000 });
|
includeRate("tunnel.fragmentedDropped", stats, new long[] { 10*60*1000, 3*60*60*1000 });
|
||||||
includeRate("tunnel.fullFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 });
|
//includeRate("tunnel.fullFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 });
|
||||||
includeRate("tunnel.smallFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 });
|
//includeRate("tunnel.smallFragments", stats, new long[] { 10*60*1000, 3*60*60*1000 });
|
||||||
includeRate("tunnel.testFailedTime", stats, new long[] { 60*60*1000 });
|
includeRate("tunnel.testFailedTime", stats, new long[] { 60*60*1000 });
|
||||||
|
|
||||||
includeRate("tunnel.buildFailure", stats, new long[] { 60*60*1000 });
|
includeRate("tunnel.buildFailure", stats, new long[] { 60*60*1000 });
|
||||||
@ -117,22 +117,26 @@ public class StatisticsManager implements Service {
|
|||||||
includeRate("tunnel.batchMultipleCount", stats, new long[] { 10*60*1000, 60*60*1000 });
|
includeRate("tunnel.batchMultipleCount", stats, new long[] { 10*60*1000, 60*60*1000 });
|
||||||
includeRate("tunnel.corruptMessage", stats, new long[] { 60*60*1000l, 3*60*60*1000l });
|
includeRate("tunnel.corruptMessage", stats, new long[] { 60*60*1000l, 3*60*60*1000l });
|
||||||
|
|
||||||
includeRate("router.throttleTunnelProbTestSlow", stats, new long[] { 60*60*1000 });
|
//includeRate("router.throttleTunnelProbTestSlow", stats, new long[] { 60*60*1000 });
|
||||||
includeRate("router.throttleTunnelProbTooFast", stats, new long[] { 60*60*1000 });
|
//includeRate("router.throttleTunnelProbTooFast", stats, new long[] { 60*60*1000 });
|
||||||
includeRate("router.throttleTunnelProcessingTime1m", stats, new long[] { 60*60*1000 });
|
//includeRate("router.throttleTunnelProcessingTime1m", stats, new long[] { 60*60*1000 });
|
||||||
|
|
||||||
includeRate("router.fastPeers", stats, new long[] { 60*60*1000 });
|
includeRate("router.fastPeers", stats, new long[] { 60*60*1000 });
|
||||||
|
|
||||||
includeRate("clock.skew", stats, new long[] { 10*60*1000, 3*60*60*1000, 24*60*60*1000 });
|
includeRate("clock.skew", stats, new long[] { 10*60*1000, 3*60*60*1000, 24*60*60*1000 });
|
||||||
|
|
||||||
includeRate("transport.sendProcessingTime", stats, new long[] { 60*60*1000 });
|
//includeRate("transport.sendProcessingTime", stats, new long[] { 60*60*1000 });
|
||||||
includeRate("jobQueue.jobRunSlow", stats, new long[] { 10*60*1000l, 60*60*1000l });
|
//includeRate("jobQueue.jobRunSlow", stats, new long[] { 10*60*1000l, 60*60*1000l });
|
||||||
includeRate("crypto.elGamal.encrypt", stats, new long[] { 60*60*1000 });
|
includeRate("crypto.elGamal.encrypt", stats, new long[] { 60*60*1000 });
|
||||||
includeRate("tunnel.participatingTunnels", stats, new long[] { 5*60*1000, 60*60*1000 });
|
includeRate("tunnel.participatingTunnels", stats, new long[] { 5*60*1000, 60*60*1000 });
|
||||||
includeRate("tunnel.testSuccessTime", stats, new long[] { 60*60*1000l, 24*60*60*1000l });
|
includeRate("tunnel.testSuccessTime", stats, new long[] { 60*60*1000l, 24*60*60*1000l });
|
||||||
includeRate("client.sendAckTime", stats, new long[] { 60*60*1000 }, true);
|
includeRate("client.sendAckTime", stats, new long[] { 60*60*1000 }, true);
|
||||||
includeRate("stream.con.sendDuplicateSize", stats, new long[] { 60*60*1000 });
|
includeRate("udp.sendConfirmTime", stats, new long[] { 10*60*1000 });
|
||||||
includeRate("stream.con.receiveDuplicateSize", stats, new long[] { 60*60*1000 });
|
includeRate("udp.sendVolleyTime", stats, new long[] { 10*60*1000 });
|
||||||
|
includeRate("udp.ignoreRecentDuplicate", stats, new long[] { 10*60*1000 });
|
||||||
|
includeRate("udp.congestionOccurred", stats, new long[] { 10*60*1000 });
|
||||||
|
//includeRate("stream.con.sendDuplicateSize", stats, new long[] { 60*60*1000 });
|
||||||
|
//includeRate("stream.con.receiveDuplicateSize", stats, new long[] { 60*60*1000 });
|
||||||
stats.setProperty("stat_uptime", DataHelper.formatDuration(_context.router().getUptime()));
|
stats.setProperty("stat_uptime", DataHelper.formatDuration(_context.router().getUptime()));
|
||||||
stats.setProperty("stat__rateKey", "avg;maxAvg;pctLifetime;[sat;satLim;maxSat;maxSatLim;][num;lifetimeFreq;maxFreq]");
|
stats.setProperty("stat__rateKey", "avg;maxAvg;pctLifetime;[sat;satLim;maxSat;maxSatLim;][num;lifetimeFreq;maxFreq]");
|
||||||
_log.debug("Publishing peer rankings");
|
_log.debug("Publishing peer rankings");
|
||||||
|
@ -281,7 +281,7 @@ class StoreJob extends JobImpl {
|
|||||||
getContext().profileManager().dbStoreSent(_peer.getIdentity().getHash(), howLong);
|
getContext().profileManager().dbStoreSent(_peer.getIdentity().getHash(), howLong);
|
||||||
getContext().statManager().addRateData("netDb.ackTime", howLong, howLong);
|
getContext().statManager().addRateData("netDb.ackTime", howLong, howLong);
|
||||||
|
|
||||||
if (_state.getSuccessful().size() >= REDUNDANCY) {
|
if (_state.getCompleteCount() >= REDUNDANCY) {
|
||||||
succeed();
|
succeed();
|
||||||
} else {
|
} else {
|
||||||
sendNext();
|
sendNext();
|
||||||
|
@ -21,6 +21,7 @@ class StoreState {
|
|||||||
private HashSet _successfulExploratoryPeers;
|
private HashSet _successfulExploratoryPeers;
|
||||||
private HashSet _failedPeers;
|
private HashSet _failedPeers;
|
||||||
private HashSet _attemptedPeers;
|
private HashSet _attemptedPeers;
|
||||||
|
private int _completeCount;
|
||||||
private volatile long _completed;
|
private volatile long _completed;
|
||||||
private volatile long _started;
|
private volatile long _started;
|
||||||
|
|
||||||
@ -34,8 +35,10 @@ class StoreState {
|
|||||||
_pendingPeers = new HashSet(16);
|
_pendingPeers = new HashSet(16);
|
||||||
_pendingPeerTimes = new HashMap(16);
|
_pendingPeerTimes = new HashMap(16);
|
||||||
_attemptedPeers = new HashSet(16);
|
_attemptedPeers = new HashSet(16);
|
||||||
if (toSkip != null)
|
if (toSkip != null) {
|
||||||
_attemptedPeers.addAll(toSkip);
|
_attemptedPeers.addAll(toSkip);
|
||||||
|
_completeCount = toSkip.size();
|
||||||
|
}
|
||||||
_failedPeers = new HashSet(16);
|
_failedPeers = new HashSet(16);
|
||||||
_successfulPeers = new HashSet(16);
|
_successfulPeers = new HashSet(16);
|
||||||
_successfulExploratoryPeers = new HashSet(16);
|
_successfulExploratoryPeers = new HashSet(16);
|
||||||
@ -75,6 +78,7 @@ class StoreState {
|
|||||||
if (completed)
|
if (completed)
|
||||||
_completed = _context.clock().now();
|
_completed = _context.clock().now();
|
||||||
}
|
}
|
||||||
|
public int getCompleteCount() { return _completeCount; }
|
||||||
|
|
||||||
public long getWhenStarted() { return _started; }
|
public long getWhenStarted() { return _started; }
|
||||||
public long getWhenCompleted() { return _completed; }
|
public long getWhenCompleted() { return _completed; }
|
||||||
@ -110,6 +114,7 @@ class StoreState {
|
|||||||
synchronized (_successfulPeers) {
|
synchronized (_successfulPeers) {
|
||||||
_successfulPeers.add(peer);
|
_successfulPeers.add(peer);
|
||||||
}
|
}
|
||||||
|
_completeCount++;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ public class TransportManager implements TransportEventListener {
|
|||||||
|
|
||||||
private final static String PROP_DISABLE_TCP = "i2np.tcp.disable";
|
private final static String PROP_DISABLE_TCP = "i2np.tcp.disable";
|
||||||
private final static String PROP_ENABLE_UDP = "i2np.udp.enable";
|
private final static String PROP_ENABLE_UDP = "i2np.udp.enable";
|
||||||
|
private static final String DEFAULT_ENABLE_UDP = "true";
|
||||||
|
|
||||||
public TransportManager(RouterContext context) {
|
public TransportManager(RouterContext context) {
|
||||||
_context = context;
|
_context = context;
|
||||||
@ -63,7 +64,9 @@ public class TransportManager implements TransportEventListener {
|
|||||||
_transports.add(t);
|
_transports.add(t);
|
||||||
}
|
}
|
||||||
String enableUDP = _context.router().getConfigSetting(PROP_ENABLE_UDP);
|
String enableUDP = _context.router().getConfigSetting(PROP_ENABLE_UDP);
|
||||||
if ( (enableUDP != null) && (Boolean.valueOf(enableUDP).booleanValue())) {
|
if (enableUDP == null)
|
||||||
|
enableUDP = DEFAULT_ENABLE_UDP;
|
||||||
|
if ("true".equalsIgnoreCase(enableUDP)) {
|
||||||
UDPTransport udp = new UDPTransport(_context);
|
UDPTransport udp = new UDPTransport(_context);
|
||||||
udp.setListener(this);
|
udp.setListener(this);
|
||||||
_transports.add(udp);
|
_transports.add(udp);
|
||||||
|
@ -529,8 +529,12 @@ public class ConnectionBuilder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// our public == X, since we are establishing the connection
|
||||||
|
byte X[] = builder.getMyPublicValueBytes();
|
||||||
|
byte Y[] = builder.getPeerPublicValueBytes();
|
||||||
|
|
||||||
// send: routerInfo + currentTime
|
// send: routerInfo + currentTime
|
||||||
// + S(routerInfo + currentTime + nonce + nextTag, routerIdent.signingKey)
|
// + S(routerInfo + currentTime + nonce + nextTag + X + Y, routerIdent.signingKey)
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||||
_context.router().getRouterInfo().writeBytes(baos);
|
_context.router().getRouterInfo().writeBytes(baos);
|
||||||
@ -540,6 +544,8 @@ public class ConnectionBuilder {
|
|||||||
|
|
||||||
baos.write(_nonce.getData());
|
baos.write(_nonce.getData());
|
||||||
baos.write(_nextConnectionTag.getData());
|
baos.write(_nextConnectionTag.getData());
|
||||||
|
baos.write(X);
|
||||||
|
baos.write(Y);
|
||||||
Signature sig = _context.dsa().sign(baos.toByteArray(),
|
Signature sig = _context.dsa().sign(baos.toByteArray(),
|
||||||
_context.keyManager().getSigningPrivateKey());
|
_context.keyManager().getSigningPrivateKey());
|
||||||
|
|
||||||
@ -556,7 +562,7 @@ public class ConnectionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read: routerInfo + status + properties
|
// read: routerInfo + status + properties
|
||||||
// + S(routerInfo + status + properties + nonce + nextTag, routerIdent.signingKey)
|
// + S(routerInfo + status + properties + nonce + nextTag + X + Y, routerIdent.signingKey)
|
||||||
try {
|
try {
|
||||||
RouterInfo peer = new RouterInfo();
|
RouterInfo peer = new RouterInfo();
|
||||||
peer.readBytes(_rawIn);
|
peer.readBytes(_rawIn);
|
||||||
@ -578,6 +584,8 @@ public class ConnectionBuilder {
|
|||||||
DataHelper.writeProperties(baos, props);
|
DataHelper.writeProperties(baos, props);
|
||||||
baos.write(_nonce.getData());
|
baos.write(_nonce.getData());
|
||||||
baos.write(_nextConnectionTag.getData());
|
baos.write(_nextConnectionTag.getData());
|
||||||
|
baos.write(X);
|
||||||
|
baos.write(Y);
|
||||||
ok = _context.dsa().verifySignature(sig, baos.toByteArray(),
|
ok = _context.dsa().verifySignature(sig, baos.toByteArray(),
|
||||||
peer.getIdentity().getSigningPublicKey());
|
peer.getIdentity().getSigningPublicKey());
|
||||||
|
|
||||||
|
@ -555,8 +555,12 @@ public class ConnectionHandler {
|
|||||||
long clockSkew = 0;
|
long clockSkew = 0;
|
||||||
boolean sigOk = false;
|
boolean sigOk = false;
|
||||||
|
|
||||||
|
// our public == Y, since we are receiving the connection
|
||||||
|
byte X[] = builder.getPeerPublicValueBytes();
|
||||||
|
byte Y[] = builder.getMyPublicValueBytes();
|
||||||
|
|
||||||
// read: routerInfo + currentTime
|
// read: routerInfo + currentTime
|
||||||
// + S(routerInfo + currentTime + nonce + nextTag, routerIdent.signingKey)
|
// + S(routerInfo + currentTime + nonce + nextTag + X + Y, routerIdent.signingKey)
|
||||||
try {
|
try {
|
||||||
RouterInfo info = new RouterInfo();
|
RouterInfo info = new RouterInfo();
|
||||||
info.readBytes(_rawIn);
|
info.readBytes(_rawIn);
|
||||||
@ -569,6 +573,8 @@ public class ConnectionHandler {
|
|||||||
DataHelper.writeDate(baos, now);
|
DataHelper.writeDate(baos, now);
|
||||||
baos.write(_nonce.getData());
|
baos.write(_nonce.getData());
|
||||||
baos.write(_nextConnectionTag.getData());
|
baos.write(_nextConnectionTag.getData());
|
||||||
|
baos.write(X);
|
||||||
|
baos.write(Y);
|
||||||
|
|
||||||
sigOk = _context.dsa().verifySignature(sig, baos.toByteArray(),
|
sigOk = _context.dsa().verifySignature(sig, baos.toByteArray(),
|
||||||
info.getIdentity().getSigningPublicKey());
|
info.getIdentity().getSigningPublicKey());
|
||||||
@ -589,7 +595,7 @@ public class ConnectionHandler {
|
|||||||
boolean reachable = verifyReachability();
|
boolean reachable = verifyReachability();
|
||||||
|
|
||||||
// send: routerInfo + status + properties
|
// send: routerInfo + status + properties
|
||||||
// + S(routerInfo + status + properties + nonce + nextTag, routerIdent.signingKey)
|
// + S(routerInfo + status + properties + nonce + nextTag + X + Y, routerIdent.signingKey)
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||||
_context.router().getRouterInfo().writeBytes(baos);
|
_context.router().getRouterInfo().writeBytes(baos);
|
||||||
@ -629,6 +635,8 @@ public class ConnectionHandler {
|
|||||||
|
|
||||||
baos.write(_nonce.getData());
|
baos.write(_nonce.getData());
|
||||||
baos.write(_nextConnectionTag.getData());
|
baos.write(_nextConnectionTag.getData());
|
||||||
|
baos.write(X);
|
||||||
|
baos.write(Y);
|
||||||
|
|
||||||
Signature sig = _context.dsa().sign(baos.toByteArray(),
|
Signature sig = _context.dsa().sign(baos.toByteArray(),
|
||||||
_context.keyManager().getSigningPrivateKey());
|
_context.keyManager().getSigningPrivateKey());
|
||||||
|
@ -89,7 +89,7 @@ public class TCPTransport extends TransportImpl {
|
|||||||
public static final int DEFAULT_ESTABLISHERS = 3;
|
public static final int DEFAULT_ESTABLISHERS = 3;
|
||||||
|
|
||||||
/** Ordered list of supported I2NP protocols */
|
/** Ordered list of supported I2NP protocols */
|
||||||
public static final int[] SUPPORTED_PROTOCOLS = new int[] { 4 }; // drop <= 0.5.0.3
|
public static final int[] SUPPORTED_PROTOCOLS = new int[] { 5 }; // drop < 0.6
|
||||||
/** blah, people shouldnt use defaults... */
|
/** blah, people shouldnt use defaults... */
|
||||||
public static final int DEFAULT_LISTEN_PORT = 8887;
|
public static final int DEFAULT_LISTEN_PORT = 8887;
|
||||||
|
|
||||||
|
@ -98,7 +98,8 @@ public class ACKSender implements Runnable {
|
|||||||
|
|
||||||
if ( (ackBitfields != null) && (ackBitfields.size() > 0) ) {
|
if ( (ackBitfields != null) && (ackBitfields.size() > 0) ) {
|
||||||
_context.statManager().addRateData("udp.sendACKCount", ackBitfields.size(), 0);
|
_context.statManager().addRateData("udp.sendACKCount", ackBitfields.size(), 0);
|
||||||
_context.statManager().addRateData("udp.sendACKRemaining", remaining, 0);
|
if (remaining > 0)
|
||||||
|
_context.statManager().addRateData("udp.sendACKRemaining", remaining, 0);
|
||||||
now = _context.clock().now();
|
now = _context.clock().now();
|
||||||
if (lastSend < 0)
|
if (lastSend < 0)
|
||||||
lastSend = now - 1;
|
lastSend = now - 1;
|
||||||
|
@ -63,8 +63,7 @@ public class EstablishmentManager {
|
|||||||
/**
|
/**
|
||||||
* Grab the active establishing state
|
* Grab the active establishing state
|
||||||
*/
|
*/
|
||||||
InboundEstablishState getInboundState(InetAddress fromHost, int fromPort) {
|
InboundEstablishState getInboundState(RemoteHostId from) {
|
||||||
RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort);
|
|
||||||
synchronized (_inboundStates) {
|
synchronized (_inboundStates) {
|
||||||
InboundEstablishState state = (InboundEstablishState)_inboundStates.get(from);
|
InboundEstablishState state = (InboundEstablishState)_inboundStates.get(from);
|
||||||
if ( (state == null) && (_log.shouldLog(Log.DEBUG)) )
|
if ( (state == null) && (_log.shouldLog(Log.DEBUG)) )
|
||||||
@ -73,8 +72,7 @@ public class EstablishmentManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutboundEstablishState getOutboundState(InetAddress fromHost, int fromPort) {
|
OutboundEstablishState getOutboundState(RemoteHostId from) {
|
||||||
RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort);
|
|
||||||
synchronized (_outboundStates) {
|
synchronized (_outboundStates) {
|
||||||
OutboundEstablishState state = (OutboundEstablishState)_outboundStates.get(from);
|
OutboundEstablishState state = (OutboundEstablishState)_outboundStates.get(from);
|
||||||
if ( (state == null) && (_log.shouldLog(Log.DEBUG)) )
|
if ( (state == null) && (_log.shouldLog(Log.DEBUG)) )
|
||||||
@ -121,12 +119,12 @@ public class EstablishmentManager {
|
|||||||
* Got a SessionRequest (initiates an inbound establishment)
|
* Got a SessionRequest (initiates an inbound establishment)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void receiveSessionRequest(RemoteHostId from, InetAddress host, int port, UDPPacketReader reader) {
|
void receiveSessionRequest(RemoteHostId from, UDPPacketReader reader) {
|
||||||
InboundEstablishState state = null;
|
InboundEstablishState state = null;
|
||||||
synchronized (_inboundStates) {
|
synchronized (_inboundStates) {
|
||||||
state = (InboundEstablishState)_inboundStates.get(from);
|
state = (InboundEstablishState)_inboundStates.get(from);
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
state = new InboundEstablishState(_context, host, port, _transport.getLocalPort());
|
state = new InboundEstablishState(_context, from.getIP(), from.getPort(), _transport.getLocalPort());
|
||||||
_inboundStates.put(from, state);
|
_inboundStates.put(from, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,10 @@ public class InboundEstablishState {
|
|||||||
/** we have completely received all of the confirmation packets */
|
/** we have completely received all of the confirmation packets */
|
||||||
public static final int STATE_CONFIRMED_COMPLETELY = 4;
|
public static final int STATE_CONFIRMED_COMPLETELY = 4;
|
||||||
|
|
||||||
public InboundEstablishState(RouterContext ctx, InetAddress remoteHost, int remotePort, int localPort) {
|
public InboundEstablishState(RouterContext ctx, byte remoteIP[], int remotePort, int localPort) {
|
||||||
_context = ctx;
|
_context = ctx;
|
||||||
_log = ctx.logManager().getLog(InboundEstablishState.class);
|
_log = ctx.logManager().getLog(InboundEstablishState.class);
|
||||||
_aliceIP = remoteHost.getAddress();
|
_aliceIP = remoteIP;
|
||||||
_alicePort = remotePort;
|
_alicePort = remotePort;
|
||||||
_remoteHostId = new RemoteHostId(_aliceIP, _alicePort);
|
_remoteHostId = new RemoteHostId(_aliceIP, _alicePort);
|
||||||
_bobPort = localPort;
|
_bobPort = localPort;
|
||||||
@ -141,7 +141,8 @@ public class InboundEstablishState {
|
|||||||
* new relay tag + Bob's signed on time
|
* new relay tag + Bob's signed on time
|
||||||
*/
|
*/
|
||||||
private void signSessionCreated() {
|
private void signSessionCreated() {
|
||||||
byte signed[] = new byte[_aliceIP.length + 2
|
byte signed[] = new byte[256 + 256 // X + Y
|
||||||
|
+ _aliceIP.length + 2
|
||||||
+ _bobIP.length + 2
|
+ _bobIP.length + 2
|
||||||
+ 4 // sent relay tag
|
+ 4 // sent relay tag
|
||||||
+ 4 // signed on time
|
+ 4 // signed on time
|
||||||
@ -149,6 +150,12 @@ public class InboundEstablishState {
|
|||||||
_sentSignedOnTime = _context.clock().now() / 1000;
|
_sentSignedOnTime = _context.clock().now() / 1000;
|
||||||
|
|
||||||
int off = 0;
|
int off = 0;
|
||||||
|
System.arraycopy(_receivedX, 0, signed, off, _receivedX.length);
|
||||||
|
off += _receivedX.length;
|
||||||
|
if (_sentY == null)
|
||||||
|
_sentY = getSentY();
|
||||||
|
System.arraycopy(_sentY, 0, signed, off, _sentY.length);
|
||||||
|
off += _sentY.length;
|
||||||
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
||||||
off += _aliceIP.length;
|
off += _aliceIP.length;
|
||||||
DataHelper.toLong(signed, off, 2, _alicePort);
|
DataHelper.toLong(signed, off, 2, _alicePort);
|
||||||
@ -166,6 +173,8 @@ public class InboundEstablishState {
|
|||||||
if (_log.shouldLog(Log.DEBUG)) {
|
if (_log.shouldLog(Log.DEBUG)) {
|
||||||
StringBuffer buf = new StringBuffer(128);
|
StringBuffer buf = new StringBuffer(128);
|
||||||
buf.append("Signing sessionCreated:");
|
buf.append("Signing sessionCreated:");
|
||||||
|
buf.append(" ReceivedX: ").append(Base64.encode(_receivedX));
|
||||||
|
buf.append(" SentY: ").append(Base64.encode(_sentY));
|
||||||
buf.append(" AliceIP: ").append(Base64.encode(_aliceIP));
|
buf.append(" AliceIP: ").append(Base64.encode(_aliceIP));
|
||||||
buf.append(" AlicePort: ").append(_alicePort);
|
buf.append(" AlicePort: ").append(_alicePort);
|
||||||
buf.append(" BobIP: ").append(Base64.encode(_bobIP));
|
buf.append(" BobIP: ").append(Base64.encode(_bobIP));
|
||||||
@ -266,13 +275,18 @@ public class InboundEstablishState {
|
|||||||
try {
|
try {
|
||||||
peer.readBytes(in);
|
peer.readBytes(in);
|
||||||
|
|
||||||
byte signed[] = new byte[_aliceIP.length + 2
|
byte signed[] = new byte[256+256 // X + Y
|
||||||
|
+ _aliceIP.length + 2
|
||||||
+ _bobIP.length + 2
|
+ _bobIP.length + 2
|
||||||
+ 4 // Alice's relay key
|
+ 4 // Alice's relay key
|
||||||
+ 4 // signed on time
|
+ 4 // signed on time
|
||||||
];
|
];
|
||||||
|
|
||||||
off = 0;
|
off = 0;
|
||||||
|
System.arraycopy(_receivedX, 0, signed, off, _receivedX.length);
|
||||||
|
off += _receivedX.length;
|
||||||
|
System.arraycopy(_sentY, 0, signed, off, _sentY.length);
|
||||||
|
off += _sentY.length;
|
||||||
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
||||||
off += _aliceIP.length;
|
off += _aliceIP.length;
|
||||||
DataHelper.toLong(signed, off, 2, _alicePort);
|
DataHelper.toLong(signed, off, 2, _alicePort);
|
||||||
|
@ -152,7 +152,8 @@ public class InboundMessageFragments /*implements UDPTransport.PartialACKSource
|
|||||||
_log.info("Message received completely! " + state);
|
_log.info("Message received completely! " + state);
|
||||||
|
|
||||||
_context.statManager().addRateData("udp.receivedCompleteTime", state.getLifetime(), state.getLifetime());
|
_context.statManager().addRateData("udp.receivedCompleteTime", state.getLifetime(), state.getLifetime());
|
||||||
_context.statManager().addRateData("udp.receivedCompleteFragments", state.getFragmentCount(), state.getLifetime());
|
if (state.getFragmentCount() > 0)
|
||||||
|
_context.statManager().addRateData("udp.receivedCompleteFragments", state.getFragmentCount(), state.getLifetime());
|
||||||
} else if (messageExpired) {
|
} else if (messageExpired) {
|
||||||
state.releaseResources();
|
state.releaseResources();
|
||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
|
@ -234,13 +234,18 @@ public class OutboundEstablishState {
|
|||||||
* new relay tag + Bob's signed on time
|
* new relay tag + Bob's signed on time
|
||||||
*/
|
*/
|
||||||
private boolean verifySessionCreated() {
|
private boolean verifySessionCreated() {
|
||||||
byte signed[] = new byte[_aliceIP.length + 2
|
byte signed[] = new byte[256+256 // X + Y
|
||||||
|
+ _aliceIP.length + 2
|
||||||
+ _bobIP.length + 2
|
+ _bobIP.length + 2
|
||||||
+ 4 // sent relay tag
|
+ 4 // sent relay tag
|
||||||
+ 4 // signed on time
|
+ 4 // signed on time
|
||||||
];
|
];
|
||||||
|
|
||||||
int off = 0;
|
int off = 0;
|
||||||
|
System.arraycopy(_sentX, 0, signed, off, _sentX.length);
|
||||||
|
off += _sentX.length;
|
||||||
|
System.arraycopy(_receivedY, 0, signed, off, _receivedY.length);
|
||||||
|
off += _receivedY.length;
|
||||||
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
||||||
off += _aliceIP.length;
|
off += _aliceIP.length;
|
||||||
DataHelper.toLong(signed, off, 2, _alicePort);
|
DataHelper.toLong(signed, off, 2, _alicePort);
|
||||||
@ -287,7 +292,8 @@ public class OutboundEstablishState {
|
|||||||
public synchronized void prepareSessionConfirmed() {
|
public synchronized void prepareSessionConfirmed() {
|
||||||
if (_sentSignedOnTime > 0)
|
if (_sentSignedOnTime > 0)
|
||||||
return;
|
return;
|
||||||
byte signed[] = new byte[_aliceIP.length + 2
|
byte signed[] = new byte[256+256 // X + Y
|
||||||
|
+ _aliceIP.length + 2
|
||||||
+ _bobIP.length + 2
|
+ _bobIP.length + 2
|
||||||
+ 4 // Alice's relay key
|
+ 4 // Alice's relay key
|
||||||
+ 4 // signed on time
|
+ 4 // signed on time
|
||||||
@ -296,6 +302,10 @@ public class OutboundEstablishState {
|
|||||||
_sentSignedOnTime = _context.clock().now() / 1000;
|
_sentSignedOnTime = _context.clock().now() / 1000;
|
||||||
|
|
||||||
int off = 0;
|
int off = 0;
|
||||||
|
System.arraycopy(_sentX, 0, signed, off, _sentX.length);
|
||||||
|
off += _sentX.length;
|
||||||
|
System.arraycopy(_receivedY, 0, signed, off, _receivedY.length);
|
||||||
|
off += _receivedY.length;
|
||||||
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
System.arraycopy(_aliceIP, 0, signed, off, _aliceIP.length);
|
||||||
off += _aliceIP.length;
|
off += _aliceIP.length;
|
||||||
DataHelper.toLong(signed, off, 2, _alicePort);
|
DataHelper.toLong(signed, off, 2, _alicePort);
|
||||||
|
@ -35,7 +35,7 @@ public class OutboundMessageFragments {
|
|||||||
/** if we can handle more messages explicitly, set this to true */
|
/** if we can handle more messages explicitly, set this to true */
|
||||||
private boolean _allowExcess;
|
private boolean _allowExcess;
|
||||||
|
|
||||||
private static final int MAX_ACTIVE = 16;
|
private static final int MAX_ACTIVE = 32;
|
||||||
// don't send a packet more than 10 times
|
// don't send a packet more than 10 times
|
||||||
static final int MAX_VOLLEYS = 10;
|
static final int MAX_VOLLEYS = 10;
|
||||||
|
|
||||||
@ -414,8 +414,10 @@ public class OutboundMessageFragments {
|
|||||||
_log.info("Received ack of " + messageId + " by " + ackedBy.toBase64()
|
_log.info("Received ack of " + messageId + " by " + ackedBy.toBase64()
|
||||||
+ " after " + state.getLifetime() + " and " + numSends + " sends");
|
+ " after " + state.getLifetime() + " and " + numSends + " sends");
|
||||||
_context.statManager().addRateData("udp.sendConfirmTime", state.getLifetime(), state.getLifetime());
|
_context.statManager().addRateData("udp.sendConfirmTime", state.getLifetime(), state.getLifetime());
|
||||||
_context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime());
|
if (state.getFragmentCount() > 1)
|
||||||
_context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount());
|
_context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime());
|
||||||
|
if (numSends > 1)
|
||||||
|
_context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount());
|
||||||
_transport.succeeded(state.getMessage());
|
_transport.succeeded(state.getMessage());
|
||||||
int numFragments = state.getFragmentCount();
|
int numFragments = state.getFragmentCount();
|
||||||
if (state.getPeer() != null) {
|
if (state.getPeer() != null) {
|
||||||
@ -494,8 +496,10 @@ public class OutboundMessageFragments {
|
|||||||
|
|
||||||
if (isComplete) {
|
if (isComplete) {
|
||||||
_context.statManager().addRateData("udp.sendConfirmTime", state.getLifetime(), state.getLifetime());
|
_context.statManager().addRateData("udp.sendConfirmTime", state.getLifetime(), state.getLifetime());
|
||||||
_context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime());
|
if (state.getFragmentCount() > 1)
|
||||||
_context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount());
|
_context.statManager().addRateData("udp.sendConfirmFragments", state.getFragmentCount(), state.getLifetime());
|
||||||
|
if (numSends > 1)
|
||||||
|
_context.statManager().addRateData("udp.sendConfirmVolley", numSends, state.getFragmentCount());
|
||||||
_transport.succeeded(state.getMessage());
|
_transport.succeeded(state.getMessage());
|
||||||
|
|
||||||
if (state.getPeer() != null) {
|
if (state.getPeer() != null) {
|
||||||
|
@ -225,10 +225,15 @@ public class OutboundMessageState {
|
|||||||
public boolean shouldSend(int fragmentNum) { return _fragmentSends[fragmentNum] >= (short)0; }
|
public boolean shouldSend(int fragmentNum) { return _fragmentSends[fragmentNum] >= (short)0; }
|
||||||
public int fragmentSize(int fragmentNum) {
|
public int fragmentSize(int fragmentNum) {
|
||||||
if (_messageBuf == null) return -1;
|
if (_messageBuf == null) return -1;
|
||||||
if (fragmentNum + 1 == _fragmentSends.length)
|
if (fragmentNum + 1 == _fragmentSends.length) {
|
||||||
return _messageBuf.getValid() % _fragmentSize;
|
int valid = _messageBuf.getValid();
|
||||||
else
|
if (valid <= _fragmentSize)
|
||||||
|
return valid;
|
||||||
|
else
|
||||||
|
return valid % _fragmentSize;
|
||||||
|
} else {
|
||||||
return _fragmentSize;
|
return _fragmentSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -241,10 +246,8 @@ public class OutboundMessageState {
|
|||||||
*/
|
*/
|
||||||
public int writeFragment(byte out[], int outOffset, int fragmentNum) {
|
public int writeFragment(byte out[], int outOffset, int fragmentNum) {
|
||||||
int start = _fragmentSize * fragmentNum;
|
int start = _fragmentSize * fragmentNum;
|
||||||
int end = start + _fragmentSize;
|
int end = start + fragmentSize(fragmentNum);
|
||||||
if (_messageBuf == null) return -1;
|
if (_messageBuf == null) return -1;
|
||||||
if (end > _messageBuf.getValid())
|
|
||||||
end = _messageBuf.getValid();
|
|
||||||
int toSend = end - start;
|
int toSend = end - start;
|
||||||
System.arraycopy(_messageBuf.getData(), start, out, outOffset, toSend);
|
System.arraycopy(_messageBuf.getData(), start, out, outOffset, toSend);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
@ -100,13 +100,12 @@ public class PacketHandler {
|
|||||||
private void handlePacket(UDPPacketReader reader, UDPPacket packet) {
|
private void handlePacket(UDPPacketReader reader, UDPPacket packet) {
|
||||||
if (packet == null) return;
|
if (packet == null) return;
|
||||||
|
|
||||||
InetAddress remAddr = packet.getPacket().getAddress();
|
RemoteHostId rem = packet.getRemoteHost();
|
||||||
int remPort = packet.getPacket().getPort();
|
PeerState state = _transport.getPeerState(rem);
|
||||||
PeerState state = _transport.getPeerState(remAddr, remPort);
|
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Packet received is not for a connected peer");
|
_log.debug("Packet received is not for a connected peer");
|
||||||
InboundEstablishState est = _establisher.getInboundState(remAddr, remPort);
|
InboundEstablishState est = _establisher.getInboundState(rem);
|
||||||
if (est != null) {
|
if (est != null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Packet received IS for an inbound establishment");
|
_log.debug("Packet received IS for an inbound establishment");
|
||||||
@ -114,7 +113,7 @@ public class PacketHandler {
|
|||||||
} else {
|
} else {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Packet received is not for an inbound establishment");
|
_log.debug("Packet received is not for an inbound establishment");
|
||||||
OutboundEstablishState oest = _establisher.getOutboundState(remAddr, remPort);
|
OutboundEstablishState oest = _establisher.getOutboundState(rem);
|
||||||
if (oest != null) {
|
if (oest != null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Packet received IS for an outbound establishment");
|
_log.debug("Packet received IS for an outbound establishment");
|
||||||
@ -152,9 +151,7 @@ public class PacketHandler {
|
|||||||
_log.info("Validation with existing con failed, but validation as reestablish/stray passed");
|
_log.info("Validation with existing con failed, but validation as reestablish/stray passed");
|
||||||
packet.decrypt(_transport.getIntroKey());
|
packet.decrypt(_transport.getIntroKey());
|
||||||
} else {
|
} else {
|
||||||
InetAddress remAddr = packet.getPacket().getAddress();
|
InboundEstablishState est = _establisher.getInboundState(packet.getRemoteHost());
|
||||||
int remPort = packet.getPacket().getPort();
|
|
||||||
InboundEstablishState est = _establisher.getInboundState(remAddr, remPort);
|
|
||||||
if (est != null) {
|
if (est != null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Packet from an existing peer IS for an inbound establishment");
|
_log.debug("Packet from an existing peer IS for an inbound establishment");
|
||||||
@ -304,13 +301,14 @@ public class PacketHandler {
|
|||||||
|
|
||||||
_context.statManager().addRateData("udp.receivePacketSkew", skew, packet.getLifetime());
|
_context.statManager().addRateData("udp.receivePacketSkew", skew, packet.getLifetime());
|
||||||
|
|
||||||
InetAddress fromHost = packet.getPacket().getAddress();
|
//InetAddress fromHost = packet.getPacket().getAddress();
|
||||||
int fromPort = packet.getPacket().getPort();
|
//int fromPort = packet.getPacket().getPort();
|
||||||
RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort);
|
//RemoteHostId from = new RemoteHostId(fromHost.getAddress(), fromPort);
|
||||||
|
RemoteHostId from = packet.getRemoteHost();
|
||||||
|
|
||||||
switch (reader.readPayloadType()) {
|
switch (reader.readPayloadType()) {
|
||||||
case UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST:
|
case UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST:
|
||||||
_establisher.receiveSessionRequest(from, fromHost, fromPort, reader);
|
_establisher.receiveSessionRequest(from, reader);
|
||||||
break;
|
break;
|
||||||
case UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED:
|
case UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED:
|
||||||
_establisher.receiveSessionConfirmed(from, reader);
|
_establisher.receiveSessionConfirmed(from, reader);
|
||||||
|
@ -541,10 +541,11 @@ public class PeerState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_context.statManager().addRateData("udp.sendACKPartial", partialIncluded, rv.size() - partialIncluded);
|
|
||||||
_lastACKSend = _context.clock().now();
|
_lastACKSend = _context.clock().now();
|
||||||
if (rv == null)
|
if (rv == null)
|
||||||
rv = Collections.EMPTY_LIST;
|
rv = Collections.EMPTY_LIST;
|
||||||
|
if (partialIncluded > 0)
|
||||||
|
_context.statManager().addRateData("udp.sendACKPartial", partialIncluded, rv.size() - partialIncluded);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public class UDPEndpoint {
|
|||||||
_receiver.startup();
|
_receiver.startup();
|
||||||
} catch (SocketException se) {
|
} catch (SocketException se) {
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Unable to bind on " + _listenPort);
|
_log.error("Unable to bind on " + _listenPort, se);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,11 +45,10 @@ public class UDPEndpoint {
|
|||||||
if (_sender != null) {
|
if (_sender != null) {
|
||||||
_sender.shutdown();
|
_sender.shutdown();
|
||||||
_receiver.shutdown();
|
_receiver.shutdown();
|
||||||
_sender = null;
|
|
||||||
_receiver = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setListenPort(int newPort) { _listenPort = newPort; }
|
||||||
public void updateListenPort(int newPort) {
|
public void updateListenPort(int newPort) {
|
||||||
if (newPort == _listenPort) return;
|
if (newPort == _listenPort) return;
|
||||||
try {
|
try {
|
||||||
|
@ -32,6 +32,7 @@ public class UDPPacket {
|
|||||||
private volatile byte[] _data;
|
private volatile byte[] _data;
|
||||||
private volatile ByteArray _dataBuf;
|
private volatile ByteArray _dataBuf;
|
||||||
private volatile int _markedType;
|
private volatile int _markedType;
|
||||||
|
private volatile RemoteHostId _remoteHost;
|
||||||
private volatile boolean _released;
|
private volatile boolean _released;
|
||||||
private volatile Exception _releasedBy;
|
private volatile Exception _releasedBy;
|
||||||
private volatile Exception _acquiredBy;
|
private volatile Exception _acquiredBy;
|
||||||
@ -78,6 +79,7 @@ public class UDPPacket {
|
|||||||
_packet = new DatagramPacket(_data, MAX_PACKET_SIZE);
|
_packet = new DatagramPacket(_data, MAX_PACKET_SIZE);
|
||||||
_initializeTime = _context.clock().now();
|
_initializeTime = _context.clock().now();
|
||||||
_markedType = -1;
|
_markedType = -1;
|
||||||
|
_remoteHost = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(int priority, long expiration, InetAddress host, int port) {
|
public void initialize(int priority, long expiration, InetAddress host, int port) {
|
||||||
@ -88,6 +90,7 @@ public class UDPPacket {
|
|||||||
//_packet.setLength(0);
|
//_packet.setLength(0);
|
||||||
_packet.setAddress(host);
|
_packet.setAddress(host);
|
||||||
_packet.setPort(port);
|
_packet.setPort(port);
|
||||||
|
_remoteHost = null;
|
||||||
_released = false;
|
_released = false;
|
||||||
_releasedBy = null;
|
_releasedBy = null;
|
||||||
}
|
}
|
||||||
@ -113,6 +116,12 @@ public class UDPPacket {
|
|||||||
*/
|
*/
|
||||||
public int getMarkedType() { verifyNotReleased(); return _markedType; }
|
public int getMarkedType() { verifyNotReleased(); return _markedType; }
|
||||||
|
|
||||||
|
public RemoteHostId getRemoteHost() {
|
||||||
|
if (_remoteHost == null)
|
||||||
|
_remoteHost = new RemoteHostId(_packet.getAddress().getAddress(), _packet.getPort());
|
||||||
|
return _remoteHost;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the packet against the MAC specified, returning true if the
|
* Validate the packet against the MAC specified, returning true if the
|
||||||
* MAC matches, false otherwise.
|
* MAC matches, false otherwise.
|
||||||
|
@ -75,7 +75,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
/** shared slow bid for unconnected peers when we want to prefer UDP */
|
/** shared slow bid for unconnected peers when we want to prefer UDP */
|
||||||
private TransportBid _slowPreferredBid;
|
private TransportBid _slowPreferredBid;
|
||||||
|
|
||||||
public static final String STYLE = "SSUv1";
|
public static final String STYLE = "SSU";
|
||||||
public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort";
|
public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort";
|
||||||
|
|
||||||
/** define this to explicitly set an external IP address */
|
/** define this to explicitly set an external IP address */
|
||||||
@ -85,11 +85,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
/**
|
/**
|
||||||
* If i2np.udp.alwaysPreferred is set, the UDP bids will always be under
|
* If i2np.udp.alwaysPreferred is set, the UDP bids will always be under
|
||||||
* the bid from the TCP transport - even if a TCP connection already
|
* the bid from the TCP transport - even if a TCP connection already
|
||||||
* exists. The default is to prefer UDP unless no UDP session exists and
|
* exists. If this is true (the default), it will always prefer UDP, otherwise
|
||||||
* a TCP connection already exists.
|
* it will prefer UDP unless no UDP session exists and a TCP connection
|
||||||
|
* already exists.
|
||||||
*/
|
*/
|
||||||
public static final String PROP_ALWAYS_PREFER_UDP = "i2np.udp.alwaysPreferred";
|
public static final String PROP_ALWAYS_PREFER_UDP = "i2np.udp.alwaysPreferred";
|
||||||
|
private static final String DEFAULT_ALWAYS_PREFER_UDP = "true";
|
||||||
|
|
||||||
/** how many relays offered to us will we use at a time? */
|
/** how many relays offered to us will we use at a time? */
|
||||||
public static final int PUBLIC_RELAY_COUNT = 3;
|
public static final int PUBLIC_RELAY_COUNT = 3;
|
||||||
@ -154,29 +155,35 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
|
|
||||||
rebuildExternalAddress();
|
rebuildExternalAddress();
|
||||||
|
|
||||||
if (_endpoint == null) {
|
int port = -1;
|
||||||
int port = -1;
|
if (_externalListenPort <= 0) {
|
||||||
if (_externalListenPort <= 0) {
|
// no explicit external port, so lets try an internal one
|
||||||
// no explicit external port, so lets try an internal one
|
String portStr = _context.getProperty(PROP_INTERNAL_PORT);
|
||||||
String portStr = _context.getProperty(PROP_INTERNAL_PORT);
|
if (portStr != null) {
|
||||||
if (portStr != null) {
|
try {
|
||||||
try {
|
port = Integer.parseInt(portStr);
|
||||||
port = Integer.parseInt(portStr);
|
} catch (NumberFormatException nfe) {
|
||||||
} catch (NumberFormatException nfe) {
|
if (_log.shouldLog(Log.ERROR))
|
||||||
if (_log.shouldLog(Log.ERROR))
|
_log.error("Invalid port specified [" + portStr + "]");
|
||||||
_log.error("Invalid port specified [" + portStr + "]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (port <= 0) {
|
|
||||||
port = 1024 + _context.random().nextInt(31*1024);
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
|
||||||
_log.info("Selecting a random port to bind to: " + port);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port = _externalListenPort;
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
|
||||||
_log.info("Binding to the explicitly specified external port: " + port);
|
|
||||||
}
|
}
|
||||||
|
if (port <= 0) {
|
||||||
|
port = 8887;
|
||||||
|
//port = 1024 + _context.random().nextInt(31*1024);
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Selecting an arbitrary port to bind to: " + port);
|
||||||
|
_context.router().setConfigSetting(PROP_INTERNAL_PORT, port+"");
|
||||||
|
// attempt to use it as our external port - this will be overridden by
|
||||||
|
// externalAddressReceived(...)
|
||||||
|
_context.router().setConfigSetting(PROP_EXTERNAL_PORT, port+"");
|
||||||
|
_context.router().saveConfig();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = _externalListenPort;
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Binding to the explicitly specified external port: " + port);
|
||||||
|
}
|
||||||
|
if (_endpoint == null) {
|
||||||
try {
|
try {
|
||||||
_endpoint = new UDPEndpoint(_context, port);
|
_endpoint = new UDPEndpoint(_context, port);
|
||||||
} catch (SocketException se) {
|
} catch (SocketException se) {
|
||||||
@ -184,6 +191,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
_log.log(Log.CRIT, "Unable to listen on the UDP port (" + port + ")", se);
|
_log.log(Log.CRIT, "Unable to listen on the UDP port (" + port + ")", se);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_endpoint.setListenPort(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_establisher == null)
|
if (_establisher == null)
|
||||||
@ -211,14 +220,14 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
|
if (_endpoint != null)
|
||||||
|
_endpoint.shutdown();
|
||||||
if (_flooder != null)
|
if (_flooder != null)
|
||||||
_flooder.shutdown();
|
_flooder.shutdown();
|
||||||
if (_refiller != null)
|
if (_refiller != null)
|
||||||
_refiller.shutdown();
|
_refiller.shutdown();
|
||||||
if (_handler != null)
|
if (_handler != null)
|
||||||
_handler.shutdown();
|
_handler.shutdown();
|
||||||
if (_endpoint != null)
|
|
||||||
_endpoint.shutdown();
|
|
||||||
if (_fragments != null)
|
if (_fragments != null)
|
||||||
_fragments.shutdown();
|
_fragments.shutdown();
|
||||||
if (_pusher != null)
|
if (_pusher != null)
|
||||||
@ -268,6 +277,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_context.router().setConfigSetting(PROP_EXTERNAL_PORT, ourPort+"");
|
||||||
|
_context.router().saveConfig();
|
||||||
|
|
||||||
if (updated)
|
if (updated)
|
||||||
_context.router().rebuildRouterInfo();
|
_context.router().rebuildRouterInfo();
|
||||||
}
|
}
|
||||||
@ -280,8 +292,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
* get the state for the peer at the given remote host/port, or null
|
* get the state for the peer at the given remote host/port, or null
|
||||||
* if no state exists
|
* if no state exists
|
||||||
*/
|
*/
|
||||||
public PeerState getPeerState(InetAddress remoteHost, int remotePort) {
|
public PeerState getPeerState(RemoteHostId hostInfo) {
|
||||||
RemoteHostId hostInfo = new RemoteHostId(remoteHost.getAddress(), remotePort);
|
|
||||||
synchronized (_peersByRemoteHost) {
|
synchronized (_peersByRemoteHost) {
|
||||||
return (PeerState)_peersByRemoteHost.get(hostInfo);
|
return (PeerState)_peersByRemoteHost.get(hostInfo);
|
||||||
}
|
}
|
||||||
@ -424,7 +435,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean alwaysPreferUDP() {
|
private boolean alwaysPreferUDP() {
|
||||||
String pref = _context.getProperty(PROP_ALWAYS_PREFER_UDP);
|
String pref = _context.getProperty(PROP_ALWAYS_PREFER_UDP, DEFAULT_ALWAYS_PREFER_UDP);
|
||||||
return (pref != null) && "true".equals(pref);
|
return (pref != null) && "true".equals(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public class HopProcessor {
|
|||||||
* and after using it at each hop so as to prevent a certain type of replay/confirmation
|
* and after using it at each hop so as to prevent a certain type of replay/confirmation
|
||||||
* attack.
|
* attack.
|
||||||
*/
|
*/
|
||||||
static final boolean USE_DOUBLE_IV_ENCRYPTION = false;
|
static final boolean USE_DOUBLE_IV_ENCRYPTION = true;
|
||||||
static final int IV_LENGTH = 16;
|
static final int IV_LENGTH = 16;
|
||||||
private static final ByteCache _cache = ByteCache.getInstance(128, IV_LENGTH);
|
private static final ByteCache _cache = ByteCache.getInstance(128, IV_LENGTH);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user