diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml index 4d7fbbe942..90f5cd6fe8 100644 --- a/apps/i2psnark/java/build.xml +++ b/apps/i2psnark/java/build.xml @@ -3,9 +3,7 @@ - - - + diff --git a/apps/i2psnark/java/src/org/klomp/snark/ExtensionHandshake.java b/apps/i2psnark/java/src/org/klomp/snark/ExtensionHandshake.java new file mode 100644 index 0000000000..fb69b044d2 --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/ExtensionHandshake.java @@ -0,0 +1,36 @@ +package org.klomp.snark; + +import java.util.HashMap; +import java.util.Map; + +import org.klomp.snark.bencode.BEncoder; +import org.klomp.snark.bencode.BEValue; + +/** + * REF: BEP 10 Extension Protocol + * @since 0.8.2 + */ +class ExtensionHandshake { + + private static final byte[] _payload = buildPayload(); + + /** + * @return bencoded data + */ + static byte[] getPayload() { + return _payload; + } + + /** just a test for now */ + private static byte[] buildPayload() { + Map handshake = new HashMap(); + Map m = new HashMap(); + m.put("foo", Integer.valueOf(99)); + m.put("bar", Integer.valueOf(101)); + handshake.put("m", m); + handshake.put("p", Integer.valueOf(6881)); + handshake.put("v", "I2PSnark"); + handshake.put("reqq", Integer.valueOf(5)); + return BEncoder.bencode(handshake); + } +} diff --git a/apps/i2psnark/java/src/org/klomp/snark/Peer.java b/apps/i2psnark/java/src/org/klomp/snark/Peer.java index 257c5ff9a2..d921f12e82 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Peer.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Peer.java @@ -66,6 +66,7 @@ public class Peer implements Comparable private long options; /** + * Outgoing connection. * Creates a disconnected peer given a PeerID, your own id and the * relevant MetaInfo. */ @@ -80,6 +81,7 @@ public class Peer implements Comparable } /** + * Incoming connection. * Creates a unconnected peer from the input and output stream got * from the socket. Note that the complete handshake (which can take * some time or block indefinitely) is done in the calling Thread to @@ -201,6 +203,7 @@ public class Peer implements Comparable // Do we need to handshake? if (din == null) { + // Outgoing connection sock = util.connect(peerID); if (_log.shouldLog(Log.DEBUG)) _log.debug("Connected to " + peerID + ": " + sock); @@ -234,6 +237,7 @@ public class Peer implements Comparable + PeerID.idencode(expected_id) + "'"); } } else { + // Incoming connection if (_log.shouldLog(Log.DEBUG)) _log.debug("Already have din [" + sock + "] with " + toString()); } @@ -242,6 +246,12 @@ public class Peer implements Comparable PeerConnectionOut out = new PeerConnectionOut(this, dout); PeerState s = new PeerState(this, listener, metainfo, in, out); + if ((options & OPTION_EXTENSION) != 0) { + if (_log.shouldLog(Log.DEBUG)) + _log.debug("Peer supports extensions, sending test message"); + out.sendExtension(0, ExtensionHandshake.getPayload()); + } + // Send our bitmap if (bitfield != null) s.out.sendBitfield(bitfield); @@ -331,12 +341,10 @@ public class Peer implements Comparable if (_log.shouldLog(Log.DEBUG)) _log.debug("Read the remote side's hash and peerID fully from " + toString()); -// if ((options & OPTION_EXTENSION) != 0) { if (options != 0) { // send them something if (_log.shouldLog(Log.DEBUG)) - //_log.debug("Peer supports extension message, what should we say? " + toString()); - _log.debug("Peer supports options 0x" + Long.toString(options, 16) + ", what should we say? " + toString()); + _log.debug("Peer supports options 0x" + Long.toString(options, 16) + ": " + toString()); } return bs; diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java index 289822df82..aa9cf2187d 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java @@ -114,8 +114,9 @@ class PeerCheckerTask extends TimerTask // Choke a percentage of them rather than all so it isn't so drastic... // unless this torrent is over the limit all by itself. + // choke 5/8 of the time when seeding and 3/8 when leeching boolean overBWLimitChoke = upload > 0 && - ((overBWLimit && random.nextBoolean()) || + ((overBWLimit && (random.nextInt(8) > (coordinator.completed() ? 2 : 4))) || (coordinator.overUpBWLimit(uploaded))); // If we are at our max uploaders and we have lots of other diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index 12e291ea89..0967f24616 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -615,13 +615,13 @@ public class PeerCoordinator implements PeerListener // share blocks rather than starting from 0 with each peer. // This is where the flaws of the snark data model are really exposed. // Could also randomize within the duplicate set rather than strict rarest-first - if (_log.shouldLog(Log.DEBUG)) - _log.debug("parallel request (end game?) for " + peer + ": piece = " + piece); + if (_log.shouldLog(Log.INFO)) + _log.info("parallel request (end game?) for " + peer + ": piece = " + piece); } } if (record) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Now requesting: piece " + piece + " priority " + piece.getPriority()); + if (_log.shouldLog(Log.INFO)) + _log.info(peer + " is now requesting: piece " + piece + " priority " + piece.getPriority()); piece.setRequested(true); } return piece.getId(); @@ -945,11 +945,11 @@ public class PeerCoordinator implements PeerListener PartialPiece pp = iter.next(); int savedPiece = pp.getPiece(); if (havePieces.get(savedPiece)) { + iter.remove(); // this is just a double-check, it should be in there for(Piece piece : wantedPieces) { if (piece.getId() == savedPiece) { piece.setRequested(true); - iter.remove(); if (_log.shouldLog(Log.INFO)) { _log.info("Restoring orphaned partial piece " + pp + " Partial list size now: " + partialPieces.size()); @@ -957,8 +957,12 @@ public class PeerCoordinator implements PeerListener return pp; } } + if (_log.shouldLog(Log.WARN)) + _log.warn("Partial piece " + pp + " NOT in wantedPieces??"); } } + if (_log.shouldLog(Log.WARN) && !partialPieces.isEmpty()) + _log.warn("Peer " + peer + " has none of our partials " + partialPieces); } // ...and this section turns this into the general move-requests-around code! // Temporary? So PeerState never calls wantPiece() directly for now... @@ -1004,7 +1008,7 @@ public class PeerCoordinator implements PeerListener } } } - return wantPiece(peer, havePieces, false) > 0; + return wantPiece(peer, havePieces, false) >= 0; } /** diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java index d32dc8ae52..38ed62029d 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java @@ -609,6 +609,9 @@ class PeerState implements DataLoader */ synchronized void addRequest() { + // no bitfield yet? nothing to request then. + if (bitfield == null) + return; boolean more_pieces = true; while (more_pieces) { diff --git a/apps/i2ptunnel/java/build.xml b/apps/i2ptunnel/java/build.xml index b17e8d9f38..f50fadd3e1 100644 --- a/apps/i2ptunnel/java/build.xml +++ b/apps/i2ptunnel/java/build.xml @@ -3,9 +3,7 @@ - - - + diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index ec38052cc0..75a276aa00 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -1573,6 +1573,7 @@ public class I2PTunnel implements Logging, EventDispatcher { * * Since file: isn't really used, this method is deprecated, * just call context.namingService.lookup() directly. + * @deprecated Don't use i2ptunnel for lookup! Use I2PAppContext.getGlobalContext().namingService().lookup(name) from i2p.jar */ public static Destination destFromName(String name) throws DataFormatException { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java index 435b309479..053fc61cea 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java @@ -42,15 +42,11 @@ public class I2PTunnelClient extends I2PTunnelClientBase { dests = new ArrayList(1); while (tok.hasMoreTokens()) { String destination = tok.nextToken(); - try { - Destination destN = I2PTunnel.destFromName(destination); - if (destN == null) - l.log("Could not resolve " + destination); - else - dests.add(destN); - } catch (DataFormatException dfe) { - l.log("Bad format parsing \"" + destination + "\""); - } + Destination destN = _context.namingService().lookup(destination); + if (destN == null) + l.log("Could not resolve " + destination); + else + dests.add(destN); } if (dests.isEmpty()) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java index 574f723feb..e151d733d7 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java @@ -278,7 +278,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R return; } - Destination clientDest = I2PTunnel.destFromName(destination); + Destination clientDest = _context.namingService().lookup(destination); if (clientDest == null) { String str; byte[] header; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 1301fcd2cb..8288e702fd 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -28,7 +28,6 @@ import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketOptions; import net.i2p.data.Base32; import net.i2p.data.Base64; -import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.util.EventDispatcher; @@ -431,11 +430,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn // Host resolvable from database, verify addresshelper key // Silently bypass correct keys, otherwise alert String destB64 = null; - try { - Destination _dest = I2PTunnel.destFromName(host); - if (_dest != null) - destB64 = _dest.toBase64(); - } catch (DataFormatException dfe) {} + Destination _dest = _context.namingService().lookup(host); + if (_dest != null) + destB64 = _dest.toBase64(); if (destB64 != null && !destB64.equals(ahelperKey)) { // Conflict: handle when URL reconstruction done @@ -721,7 +718,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn if ("i2p".equals(host)) clientDest = null; else - clientDest = I2PTunnel.destFromName(destination); + clientDest = _context.namingService().lookup(destination); if (clientDest == null) { //l.log("Could not resolve " + destination + "."); @@ -814,17 +811,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn * @return b32hash.b32.i2p, or "i2p" on lookup failure. * Prior to 0.7.12, returned b64 key */ - private final static String getHostName(String host) { + private final String getHostName(String host) { if (host == null) return null; if (host.length() == 60 && host.toLowerCase().endsWith(".b32.i2p")) return host; - try { - Destination dest = I2PTunnel.destFromName(host); - if (dest == null) return "i2p"; - return Base32.encode(dest.calculateHash().getData()) + ".b32.i2p"; - } catch (DataFormatException dfe) { - return "i2p"; - } + Destination dest = _context.namingService().lookup(host); + if (dest == null) return "i2p"; + return Base32.encode(dest.calculateHash().getData()) + ".b32.i2p"; } /** @@ -947,12 +940,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn // Skip jump servers we don't know String jumphost = jurl.substring(7); // "http://" jumphost = jumphost.substring(0, jumphost.indexOf('/')); - try { - Destination dest = I2PTunnel.destFromName(jumphost); - if (dest == null) continue; - } catch (DataFormatException dfe) { - continue; - } + Destination dest = I2PAppContext.getGlobalContext().namingService().lookup(jumphost); + if (dest == null) continue; out.write("
0) { - try { - _otherDest = I2PTunnel.destFromName(destination); - } catch (DataFormatException dfe) {} + _otherDest = _context.namingService().lookup(destination); if (_otherDest == null) { l.log("Could not resolve " + destination); throw new RuntimeException("failed to create session - could not resolve " + destination); diff --git a/apps/ministreaming/java/build.xml b/apps/ministreaming/java/build.xml index ca0889042c..c22676d264 100644 --- a/apps/ministreaming/java/build.xml +++ b/apps/ministreaming/java/build.xml @@ -3,7 +3,7 @@ - + @@ -45,9 +45,7 @@ - - diff --git a/apps/routerconsole/java/build.xml b/apps/routerconsole/java/build.xml index 8b08c0de86..d544e59aca 100644 --- a/apps/routerconsole/java/build.xml +++ b/apps/routerconsole/java/build.xml @@ -3,12 +3,10 @@ - - - + - + @@ -235,13 +233,7 @@ - - - - - - diff --git a/apps/sam/java/build.xml b/apps/sam/java/build.xml index 6a987b3411..57aeff9947 100644 --- a/apps/sam/java/build.xml +++ b/apps/sam/java/build.xml @@ -3,9 +3,7 @@ - - - + @@ -69,13 +67,7 @@ - - - - - - diff --git a/apps/streaming/java/build.xml b/apps/streaming/java/build.xml index 7740a60226..dff6fbf1d5 100644 --- a/apps/streaming/java/build.xml +++ b/apps/streaming/java/build.xml @@ -3,8 +3,7 @@ - - + @@ -62,11 +61,7 @@ - - - - diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml index fb43716144..9ab38ce42e 100644 --- a/apps/susimail/build.xml +++ b/apps/susimail/build.xml @@ -3,7 +3,7 @@ - + diff --git a/apps/systray/java/build.xml b/apps/systray/java/build.xml index 1597f20b35..9d48f902cb 100644 --- a/apps/systray/java/build.xml +++ b/apps/systray/java/build.xml @@ -3,7 +3,7 @@ - + @@ -55,10 +55,7 @@ - - - diff --git a/build.xml b/build.xml index de35251916..f0c1c49739 100644 --- a/build.xml +++ b/build.xml @@ -62,33 +62,79 @@ - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + @@ -98,6 +144,7 @@ + diff --git a/history.txt b/history.txt index 62a3e76e70..57a905e8c7 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,12 @@ +2010-11-28 zzz + * Build: Move all dependencies to top-level build.xml, + so each sub-build.xml is only executed once + * i2psnark: + - Fix NPE and other partials bugs + - More extension message stubbing + - Log tweaks + * I2PTunnel: Deprecate destFromName() + 2010-11-27 zzz * Build: - Add man pages to package diff --git a/router/java/build.xml b/router/java/build.xml index efb0b3091a..69f6b41094 100644 --- a/router/java/build.xml +++ b/router/java/build.xml @@ -3,7 +3,7 @@ - + @@ -131,9 +131,7 @@ - - diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index e36cd3b143..7f4edb9752 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 12; + public final static long BUILD = 13; /** for example "-test" */ public final static String EXTRA = "";