From 01b67acfa017ef92e5215431396b1f8c4b56a2a8 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Tue, 28 Dec 2010 15:46:45 +0000 Subject: [PATCH] - Catch OOM when creating torrent (tickets #364 and #366) - Fix changing 'use open trackers' config setting (old bug) - More TrackerClient fixes for no primary announce - More BEValue.toString() improvements for debugging --- .../src/org/klomp/snark/I2PSnarkUtil.java | 15 +++++--- .../java/src/org/klomp/snark/Snark.java | 2 + .../src/org/klomp/snark/SnarkManager.java | 7 +++- .../src/org/klomp/snark/TrackerClient.java | 10 ++--- .../src/org/klomp/snark/bencode/BEValue.java | 37 +++++++++++++++---- .../org/klomp/snark/web/I2PSnarkServlet.java | 2 + 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index 775d4cc4ab..16edc12f65 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -60,6 +60,7 @@ public class I2PSnarkUtil { private int _maxConnections; private File _tmpDir; private int _startupDelay; + private boolean _shouldUseOT; private KRPC _krpc; public static final int DEFAULT_STARTUP_DELAY = 3; @@ -83,6 +84,7 @@ public class I2PSnarkUtil { _maxUpBW = DEFAULT_MAX_UP_BW; _maxConnections = MAX_CONNECTIONS; _startupDelay = DEFAULT_STARTUP_DELAY; + _shouldUseOT = DEFAULT_USE_OPENTRACKERS; // This is used for both announce replies and .torrent file downloads, // so it must be available even if not connected to I2CP. // so much for multiple instances @@ -425,10 +427,10 @@ public class I2PSnarkUtil { /** comma delimited list open trackers to use as backups */ /** sorted map of name to announceURL=baseURL */ - public List getOpenTrackers() { + public List<String> getOpenTrackers() { if (!shouldUseOpenTrackers()) return null; - List rv = new ArrayList(1); + List<String> rv = new ArrayList(1); String trackers = getOpenTrackerString(); StringTokenizer tok = new StringTokenizer(trackers, ", "); while (tok.hasMoreTokens()) @@ -439,11 +441,12 @@ public class I2PSnarkUtil { return rv; } + public void setUseOpenTrackers(boolean yes) { + _shouldUseOT = yes; + } + public boolean shouldUseOpenTrackers() { - String rv = (String) _opts.get(PROP_USE_OPENTRACKERS); - if (rv == null) - return DEFAULT_USE_OPENTRACKERS; - return Boolean.valueOf(rv).booleanValue(); + return _shouldUseOT; } /** diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java index d114fe0ee2..e3a99bdc9b 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java @@ -394,6 +394,8 @@ public class Snark */ else fatal("Cannot open '" + torrent + "'", ioe); + } catch (OutOfMemoryError oom) { + fatal("ERROR - Out of memory, cannot create torrent " + torrent + ": " + oom.getMessage()); } finally { if (in != null) try { in.close(); } catch (IOException ioe) {} diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 1e5ba10bf2..6ac7261e3e 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -263,7 +263,9 @@ public class SnarkManager implements Snark.CompleteListener { String ot = _config.getProperty(I2PSnarkUtil.PROP_OPENTRACKERS); if (ot != null) _util.setOpenTrackerString(ot); - // FIXME set util use open trackers property somehow + String useOT = _config.getProperty(I2PSnarkUtil.PROP_USE_OPENTRACKERS); + boolean bOT = useOT == null || Boolean.valueOf(useOT).booleanValue(); + _util.setUseOpenTrackers(bOT); getDataDir().mkdirs(); } @@ -434,6 +436,7 @@ public class SnarkManager implements Snark.CompleteListener { addMessage(_("Enabled open trackers - torrent restart required to take effect.")); else addMessage(_("Disabled open trackers - torrent restart required to take effect.")); + _util.setUseOpenTrackers(useOpenTrackers); changed = true; } if (openTrackers != null) { @@ -605,6 +608,8 @@ public class SnarkManager implements Snark.CompleteListener { if (sfile.exists()) sfile.delete(); return; + } catch (OutOfMemoryError oom) { + addMessage(_("ERROR - Out of memory, cannot create torrent from {0}", sfile.getName()) + ": " + oom.getMessage()); } finally { if (fis != null) try { fis.close(); } catch (IOException ioe) {} } diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java index d03753d6bd..9cf9f7f097 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java +++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java @@ -137,18 +137,18 @@ public class TrackerClient extends I2PAppThread // the primary tracker, that we don't add it twice. // todo: check for b32 matches as well trackers = new ArrayList(2); - String primary; + String primary = null; if (meta != null) { primary = meta.getAnnounce(); if (isValidAnnounce(primary)) { trackers.add(new Tracker(meta.getAnnounce(), true)); + _log.debug("Announce: [" + primary + "] infoHash: " + infoHash); } else { _log.warn("Skipping invalid or non-i2p announce: " + primary); } - } else { - primary = ""; } - _log.debug("Announce: [" + primary + "] infoHash: " + infoHash); + if (primary == null) + primary = ""; List tlist = _util.getOpenTrackers(); if (tlist != null) { for (int i = 0; i < tlist.size(); i++) { @@ -179,7 +179,7 @@ public class TrackerClient extends I2PAppThread } } - if (tlist.isEmpty()) { + if (trackers.isEmpty()) { // FIXME really need to get this message to the gui stop = true; _log.error("No valid trackers for infoHash: " + infoHash); diff --git a/apps/i2psnark/java/src/org/klomp/snark/bencode/BEValue.java b/apps/i2psnark/java/src/org/klomp/snark/bencode/BEValue.java index 75a63bab19..4cae2881ae 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/bencode/BEValue.java +++ b/apps/i2psnark/java/src/org/klomp/snark/bencode/BEValue.java @@ -180,15 +180,36 @@ public class BEValue String valueString; if (value instanceof byte[]) { + // try to do a nice job for debugging byte[] bs = (byte[])value; - // XXX - Stupid heuristic... and not UTF-8 - //if (bs.length <= 12) - // valueString = new String(bs); - //else - // valueString = "bytes:" + bs.length; - if (bs.length <= 32) - valueString = bs.length + " bytes: " + Base64.encode(bs); - else + if (bs.length == 0) + valueString = "0 bytes"; + else if (bs.length <= 32) { + StringBuilder buf = new StringBuilder(32); + boolean bin = false; + for (int i = 0; i < bs.length; i++) { + int b = bs[i] & 0xff; + // no UTF-8 + if (b < ' ' || b > 0x7e) { + bin = true; + break; + } + } + if (bin && bs.length <= 8) { + buf.append(bs.length).append(" bytes: 0x"); + for (int i = 0; i < bs.length; i++) { + int b = bs[i] & 0xff; + if (b < 16) + buf.append('0'); + buf.append(Integer.toHexString(b)); + } + } else if (bin) { + buf.append(bs.length).append(" bytes: ").append(Base64.encode(bs)); + } else { + buf.append('"').append(new String(bs)).append('"'); + } + valueString = buf.toString(); + } else valueString = bs.length + " bytes"; } else diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 6b82734555..5890c0df65 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -1902,6 +1902,8 @@ private static class FetchAndAdd implements Runnable { } } catch (IOException ioe) { _manager.addMessage(_("Torrent at {0} was not valid", urlify(_url)) + ": " + ioe.getMessage()); + } catch (OutOfMemoryError oom) { + _manager.addMessage(_("ERROR - Out of memory, cannot create torrent from {0}", urlify(_url)) + ": " + oom.getMessage()); } finally { try { if (in != null) in.close(); } catch (IOException ioe) {} } -- GitLab