diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java
index 608d36ba89..5e0a8702e4 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java
@@ -159,9 +159,28 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
}
}
+ private static final String PROP_HANDLER_COUNT = "i2ptunnel.blockingHandlerCount";
+ private static final int DEFAULT_HANDLER_COUNT = 10;
+
+ protected int getHandlerCount() {
+ int rv = DEFAULT_HANDLER_COUNT;
+ String cnt = getTunnel().getClientOptions().getProperty(PROP_HANDLER_COUNT);
+ if (cnt != null) {
+ try {
+ rv = Integer.parseInt(cnt);
+ if (rv <= 0)
+ rv = DEFAULT_HANDLER_COUNT;
+ } catch (NumberFormatException nfe) {
+ rv = DEFAULT_HANDLER_COUNT;
+ }
+ }
+ return rv;
+ }
+
public void run() {
I2PServerSocket i2pss = sockMgr.getServerSocket();
- for (int i = 0; i < 5; i++) {
+ int handlers = getHandlerCount();
+ for (int i = 0; i < handlers; i++) {
I2PThread handler = new I2PThread(new Handler(i2pss), "Handle Server " + i);
handler.start();
}
diff --git a/core/java/src/net/i2p/CoreVersion.java b/core/java/src/net/i2p/CoreVersion.java
index 17d8502055..7d72508d35 100644
--- a/core/java/src/net/i2p/CoreVersion.java
+++ b/core/java/src/net/i2p/CoreVersion.java
@@ -14,8 +14,8 @@ package net.i2p;
*
*/
public class CoreVersion {
- public final static String ID = "$Revision: 1.35 $ $Date: 2005/04/20 15:14:20 $";
- public final static String VERSION = "0.6";
+ public final static String ID = "$Revision: 1.36 $ $Date: 2005/07/27 14:04:49 $";
+ public final static String VERSION = "0.6.0.1";
public static void main(String args[]) {
System.out.println("I2P Core version: " + VERSION);
diff --git a/history.txt b/history.txt
index 76b8cda67c..6e75abf083 100644
--- a/history.txt
+++ b/history.txt
@@ -1,4 +1,11 @@
-$Id: history.txt,v 1.220 2005/08/01 08:35:11 duck Exp $
+$Id: history.txt,v 1.221 2005/08/01 22:26:51 duck Exp $
+
+* 2005-08-03 0.6.0.1 released
+
+2005-08-03 jrandom
+ * Backed out an inadvertant change to the netDb store redundancy factor.
+ * Verify tunnel participant caching.
+ * Logging cleanup
2005-08-01 duck
* Update IzPack to 3.7.2 (build 2005.04.22). This fixes bug #82.
diff --git a/initialNews.xml b/initialNews.xml
index b6c585ea78..b15b7694b5 100644
--- a/initialNews.xml
+++ b/initialNews.xml
@@ -1,5 +1,5 @@
-
-
+
i2p
- 0.6
+ 0.6.0.1
diff --git a/news.xml b/news.xml
index 87bc3e5b73..193f4ad4f5 100644
--- a/news.xml
+++ b/news.xml
@@ -1,5 +1,5 @@
-
-
+ $Id: udp.html,v 1.13 2005/05/01 15:08:08 jrandom Exp $
+$Id: udp.html,v 1.14 2005/07/27 14:04:07 jrandom Exp $
Secure Semireliable UDP (SSU)
DRAFT
@@ -21,8 +21,8 @@ indirect address, for using a third party to introduce the peer.
There is no restriction on the number of addresses a peer may have.
- Direct: udp://host:port/introKey
- Indirect: udp://tag@relayhost:port/relayIntroKey/targetIntroKey
+ Direct: ssu://host:port/introKey[?opts=[A-Z]*]
+ Indirect: ssu://tag@relayhost:port/relayIntroKey/targetIntroKey[?opts=[A-Z]*]
These introduction keys are delivered through an external channel
@@ -36,6 +36,10 @@ located. In addition, the peer establishing the connection must
already know the public keys of the peer they are connecting to (but
not necessary to any intermediary relay peer).
+Each of the addresses may also expose a series of options - special
+capabilities of that particular peer. For a list of available
+capabilities, see below.
+
All UDP datagrams begin with a MAC and an IV, followed by a variable
@@ -433,6 +437,41 @@ bits 10-23: fragment size
+----+----+----+----+----+----+----+----+
+
+
+Peer: |
+ Any |
+Data: |
+
+ - 4 byte nonce
+ - 1 byte IP address size
+ - that many byte representation of Alice's IP address
+ - 2 byte port number
+ - Alice's introduction key
+ - N bytes, currently uninterpreted
+ |
+Key used: |
+ introKey (or sessionKey if the connection has already been established) |
+
+
+
+ +----+----+----+----+----+----+----+----+
+ | test nonce |size| that many |
+ +----+----+----+----+----+ |
+ |bytes making up Alice's IP address |
+ |----+----+----+----+----+----+----+----+
+ | Port (A)| Alice or Charlie's |
+ +----+----+ |
+ | introduction key (Alice's is sent to |
+ | Bob and Charlie, while Charlie's is | |
+ | sent to Alice) |
+ | +----+----+----+----+----+----+
+ | | arbitrary amount of |
+ |----+----+ |
+ | uninterpreted data |
+ +----+----+----+----+----+----+----+----+
+
+
SSU's need for only semireliable delivery, TCP-friendly operation,
@@ -524,6 +563,74 @@ are not in any particular order - in fact, they are likely to be
entirely random. The SSU layer makes no attempt at messageId
replay prevention - higher layers should take that into account.
+
+
+The automation of collaborative reachability testing for peers is
+enabled by a sequence of PeerTest messages. With its proper
+execution, a peer will be able to determine their own reachability
+and may update its behavior accordingly. The testing process is
+quite simple:
+
+
+ Alice Bob Charlie
+ PeerTest ------------------>
+ <-------------PeerTest PeerTest------------->
+ <------------------------------------------PeerTest
+ PeerTest------------------------------------------>
+ <------------------------------------------PeerTest
+
+
+Each of the PeerTest messages carry a nonce identifying the
+test series itself, as initialized by Alice. If Alice doesn't
+get a particular message that she expects, she will retransmit
+accordingly, and based upon the data received or the messages
+missing, she will know her reachability. The various end states
+that may be reached are as follows:
+
+
+- If she doesn't receive a response from Bob, she will retransmit
+up to a certain number of times, but if no response ever arrives,
+she will know that her firewall or NAT is somehow misconfigured,
+rejecting all inbound UDP packets even in direct response to an
+outbound packet. Alternately, Bob may be down.
+
+- If Alice doesn't receive a PeerTest message with the
+expected nonce from a third party (Charlie), she will retransmit
+her initial request to Bob up to a certain number of times, even
+if she has received Bob's reply already. If Charlie's first message
+still doesn't get through but Bob's does, she knows that she is
+behind a NAT or firewall that is rejecting unsolicited connection
+attempts and that port forwarding is not operating properly (the
+IP and port that Bob offered up should be forwarded).
+
+- If Alice receives Bob's PeerTest message and both of Charlie's
+PeerTest messages but the enclosed IP and port numbers in Bob's
+and Charlie's second messages don't match, she knows that she is
+behind a symmetric NAT, rewriting all of her outbound packets with
+different 'from' ports for each peer contacted. She will need to
+explicitly forward a port and always have that port exposed for
+remote connectivity, ignoring further port discovery.
+
+- If Alice receives Charlie's first message but not his second,
+she will retransmit her PeerTest message to Charlie up to a
+certain number of times, but if no response is received she knows
+that Charlie is either confused or no longer online.
+
+
+Alice should choose Bob arbitrarily from known peers who seem
+to be capable of participating in peer tests. Bob in turn should
+choose Charlie arbitrarily from peers that he knows who seem to be
+capable of participating in peer tests and who are on a different
+IP from both Bob and Alice. If the first error condition occurs
+(Alice doesn't get PeerTest messages from Bob), Alice may decide
+to designate a new peer as Bob and try again with a different nonce.
+
+Alice's introduction key is included in all of the PeerTest
+messages so that she doesn't need to already have an established
+session with Bob and so that Charlie can contact her without knowing
+any additional information. Alice may go on to establish a session
+with either Bob or Charlie, but it is not required.
+
@@ -594,3 +701,16 @@ replay prevention - higher layers should take that into account.
| |
+----+----+----+----+----+----+----+----+
+
+
+
+
+ - A
+ - If the peer address contains the 'A' capability, that means
+ they are willing and able to participate in peer tests as
+ a 'Bob' or 'Charlie'.
+ - B
+ - If the peer address contains the 'B' capability, that means
+ they are willing and able to serve as an introducer - serving
+ as a Bob for an otherwise unreachable Alice.
+
\ No newline at end of file
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index e42bdcc743..54046c1f29 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
- public final static String ID = "$Revision: 1.209 $ $Date: 2005/07/27 14:03:43 $";
- public final static String VERSION = "0.6";
- public final static long BUILD = 1;
+ public final static String ID = "$Revision: 1.210 $ $Date: 2005/07/31 16:35:27 $";
+ public final static String VERSION = "0.6.0.1";
+ public final static long BUILD = 0;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID);
diff --git a/router/java/src/net/i2p/router/message/SendMessageDirectJob.java b/router/java/src/net/i2p/router/message/SendMessageDirectJob.java
index 5ab565ad70..10a9bf13b9 100644
--- a/router/java/src/net/i2p/router/message/SendMessageDirectJob.java
+++ b/router/java/src/net/i2p/router/message/SendMessageDirectJob.java
@@ -74,8 +74,8 @@ public class SendMessageDirectJob extends JobImpl {
long now = getContext().clock().now();
if (_expiration < now) {
- if (_log.shouldLog(Log.ERROR))
- _log.error("Timed out sending message " + _message + " directly (expiration = "
+ if (_log.shouldLog(Log.WARN))
+ _log.warn("Timed out sending message " + _message + " directly (expiration = "
+ new Date(_expiration) + ") to " + _targetHash.toBase64(), getAddedBy());
if (_onFail != null)
getContext().jobQueue().addJob(_onFail);
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java
index 3d7c41d3a7..ffdf5e9045 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java
@@ -39,7 +39,7 @@ class StoreJob extends JobImpl {
private PeerSelector _peerSelector;
private final static int PARALLELIZATION = 3; // how many sent at a time
- private final static int REDUNDANCY = 3; // we want the data sent to 6 peers
+ private final static int REDUNDANCY = 10; // we want the data sent to 10 peers
/**
* additionally send to 1 outlier(s), in case all of the routers chosen in our
* REDUNDANCY set are attacking us by accepting DbStore messages but dropping
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java
index 743718b96a..df137136d6 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java
@@ -179,8 +179,8 @@ public class UDPReceiver {
if (_log.shouldLog(Log.INFO))
_log.info("Changing ports...");
} else {
- if (_log.shouldLog(Log.ERROR))
- _log.error("Error receiving", ioe);
+ if (_log.shouldLog(Log.WARN))
+ _log.warn("Error receiving", ioe);
}
packet.release();
}
diff --git a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java
index 484cab14ec..aa7792f6b5 100644
--- a/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java
+++ b/router/java/src/net/i2p/router/tunnel/TunnelParticipant.java
@@ -142,14 +142,18 @@ public class TunnelParticipant {
}
public String getName() { return "forward a tunnel message"; }
public void runJob() {
- RouterInfo ri = _context.netDb().lookupRouterInfoLocally(_config.getSendTo());
- if (ri != null) {
- _nextHopCache = ri;
- send(_config, _msg, ri);
+ if (_nextHopCache != null) {
+ send(_config, _msg, _nextHopCache);
} else {
- if (_log.shouldLog(Log.ERROR))
- _log.error("Lookup the nextHop (" + _config.getSendTo().toBase64().substring(0,4)
- + " failed! where do we go for " + _config + "? msg dropped: " + _msg);
+ RouterInfo ri = _context.netDb().lookupRouterInfoLocally(_config.getSendTo());
+ if (ri != null) {
+ _nextHopCache = ri;
+ send(_config, _msg, ri);
+ } else {
+ if (_log.shouldLog(Log.ERROR))
+ _log.error("Lookup the nextHop (" + _config.getSendTo().toBase64().substring(0,4)
+ + " failed! where do we go for " + _config + "? msg dropped: " + _msg);
+ }
}
}
}
@@ -162,6 +166,9 @@ public class TunnelParticipant {
}
public String getName() { return "timeout looking for next hop info"; }
public void runJob() {
+ if (_nextHopCache != null)
+ return;
+
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(_config.getSendTo());
if (ri != null) {
_nextHopCache = ri;