forked from I2P_Developers/i2p.i2p
merge of '639a99d15ec0e7cbf0b44fd44564a6ae304b8673'
and '6b24962b7b3513e22153068b62922cabebb2dee4'
This commit is contained in:
@ -105,6 +105,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
private static final String PROP_META_UPLOADED = "uploaded";
|
||||
private static final String PROP_META_ADDED = "added";
|
||||
private static final String PROP_META_COMPLETED = "completed";
|
||||
private static final String PROP_META_INORDER = "inOrder";
|
||||
private static final String PROP_META_MAGNET = "magnet";
|
||||
private static final String PROP_META_MAGNET_DN = "magnet_dn";
|
||||
private static final String PROP_META_MAGNET_TR = "magnet_tr";
|
||||
@ -1759,7 +1760,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
addMessage(_t("Torrent with this info hash is already running: {0}", snark.getBaseName()));
|
||||
return false;
|
||||
} else if (bitfield != null) {
|
||||
saveTorrentStatus(metainfo, bitfield, null, baseFile, true, 0, true); // no file priorities
|
||||
saveTorrentStatus(metainfo, bitfield, null, false, baseFile, true, 0, true); // no file priorities
|
||||
}
|
||||
// so addTorrent won't recheck
|
||||
if (filename == null) {
|
||||
@ -1898,19 +1899,21 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
return;
|
||||
Properties config = getConfig(snark);
|
||||
String pri = config.getProperty(PROP_META_PRIORITY);
|
||||
if (pri == null)
|
||||
return;
|
||||
int filecount = metainfo.getFiles().size();
|
||||
int[] rv = new int[filecount];
|
||||
String[] arr = DataHelper.split(pri, ",");
|
||||
for (int i = 0; i < filecount && i < arr.length; i++) {
|
||||
if (arr[i].length() > 0) {
|
||||
try {
|
||||
rv[i] = Integer.parseInt(arr[i]);
|
||||
} catch (Throwable t) {}
|
||||
if (pri != null) {
|
||||
int filecount = metainfo.getFiles().size();
|
||||
int[] rv = new int[filecount];
|
||||
String[] arr = DataHelper.split(pri, ",");
|
||||
for (int i = 0; i < filecount && i < arr.length; i++) {
|
||||
if (arr[i].length() > 0) {
|
||||
try {
|
||||
rv[i] = Integer.parseInt(arr[i]);
|
||||
} catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
storage.setFilePriorities(rv);
|
||||
}
|
||||
storage.setFilePriorities(rv);
|
||||
boolean inOrder = Boolean.parseBoolean(config.getProperty(PROP_META_INORDER));
|
||||
storage.setInOrder(inOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2017,7 +2020,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
Storage storage = snark.getStorage();
|
||||
if (meta == null || storage == null)
|
||||
return;
|
||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), storage.getInOrder(),
|
||||
storage.getBase(), storage.getPreserveFileNames(),
|
||||
snark.getUploaded(), snark.isStopped(), comments);
|
||||
}
|
||||
@ -2034,24 +2037,24 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
* @param priorities may be null
|
||||
* @param base may be null
|
||||
*/
|
||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
|
||||
File base, boolean preserveNames, long uploaded, boolean stopped) {
|
||||
saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, null);
|
||||
saveTorrentStatus(metainfo, bitfield, priorities, inOrder, base, preserveNames, uploaded, stopped, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* @param comments null for no change
|
||||
* @since 0.9.31
|
||||
*/
|
||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
|
||||
File base, boolean preserveNames, long uploaded, boolean stopped,
|
||||
Boolean comments) {
|
||||
synchronized (_configLock) {
|
||||
locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, comments);
|
||||
locked_saveTorrentStatus(metainfo, bitfield, priorities, inOrder, base, preserveNames, uploaded, stopped, comments);
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities, boolean inOrder,
|
||||
File base, boolean preserveNames, long uploaded, boolean stopped,
|
||||
Boolean comments) {
|
||||
byte[] ih = metainfo.getInfoHash();
|
||||
@ -2077,6 +2080,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
config.setProperty(PROP_META_UPLOADED, Long.toString(uploaded));
|
||||
boolean running = !stopped;
|
||||
config.setProperty(PROP_META_RUNNING, Boolean.toString(running));
|
||||
config.setProperty(PROP_META_INORDER, Boolean.toString(inOrder));
|
||||
if (base != null)
|
||||
config.setProperty(PROP_META_BASE, base.getAbsolutePath());
|
||||
if (comments != null)
|
||||
@ -2095,7 +2099,9 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
// generate string like -5,,4,3,,,,,,-2 where no number is zero.
|
||||
StringBuilder buf = new StringBuilder(2 * priorities.length);
|
||||
for (int i = 0; i < priorities.length; i++) {
|
||||
if (priorities[i] != 0)
|
||||
// only output if !inOrder || !skipped so the string isn't too long
|
||||
if (priorities[i] != 0 &&
|
||||
(!inOrder || priorities[i] < 0))
|
||||
buf.append(Integer.toString(priorities[i]));
|
||||
if (i != priorities.length - 1)
|
||||
buf.append(',');
|
||||
@ -2443,7 +2449,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
MetaInfo meta = snark.getMetaInfo();
|
||||
Storage storage = snark.getStorage();
|
||||
if (meta != null && storage != null)
|
||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(), storage.getInOrder(),
|
||||
storage.getBase(), storage.getPreserveFileNames(), snark.getUploaded(),
|
||||
snark.isStopped());
|
||||
}
|
||||
@ -2467,7 +2473,7 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
||||
snark.stopTorrent();
|
||||
return null;
|
||||
}
|
||||
saveTorrentStatus(meta, storage.getBitField(), null,
|
||||
saveTorrentStatus(meta, storage.getBitField(), null, false,
|
||||
storage.getBase(), storage.getPreserveFileNames(), 0,
|
||||
snark.isStopped());
|
||||
// temp for addMessage() in case canonical throws
|
||||
|
@ -25,11 +25,14 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.Serializable;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -72,6 +75,7 @@ public class Storage implements Closeable
|
||||
private final boolean _preserveFileNames;
|
||||
private boolean changed;
|
||||
private volatile boolean _isChecking;
|
||||
private boolean _inOrder;
|
||||
private final AtomicInteger _allocateCount = new AtomicInteger();
|
||||
private final AtomicInteger _checkProgress = new AtomicInteger();
|
||||
|
||||
@ -82,6 +86,8 @@ public class Storage implements Closeable
|
||||
/** The maximum number of pieces in a torrent. */
|
||||
public static final int MAX_PIECES = 32*1024;
|
||||
public static final long MAX_TOTAL_SIZE = MAX_PIECE_SIZE * (long) MAX_PIECES;
|
||||
public static final int PRIORITY_SKIP = -9;
|
||||
public static final int PRIORITY_NORMAL = 0;
|
||||
|
||||
private static final Map<String, String> _filterNameCache = new ConcurrentHashMap<String, String>();
|
||||
|
||||
@ -145,7 +151,7 @@ public class Storage implements Closeable
|
||||
_torrentFiles = getFiles(baseFile);
|
||||
|
||||
long total = 0;
|
||||
ArrayList<Long> lengthsList = new ArrayList<Long>();
|
||||
ArrayList<Long> lengthsList = new ArrayList<Long>(_torrentFiles.size());
|
||||
for (TorrentFile tf : _torrentFiles)
|
||||
{
|
||||
long length = tf.length;
|
||||
@ -178,7 +184,7 @@ public class Storage implements Closeable
|
||||
bitfield = new BitField(pieces);
|
||||
needed = 0;
|
||||
|
||||
List<List<String>> files = new ArrayList<List<String>>();
|
||||
List<List<String>> files = new ArrayList<List<String>>(_torrentFiles.size());
|
||||
for (TorrentFile tf : _torrentFiles)
|
||||
{
|
||||
List<String> file = new ArrayList<String>();
|
||||
@ -494,6 +500,60 @@ public class Storage implements Closeable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return as last set, default false
|
||||
* @since 0.9.36
|
||||
*/
|
||||
public boolean getInOrder() {
|
||||
return _inOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call AFTER setFilePriorites() so we know what's skipped
|
||||
* @param yes enable or not
|
||||
* @since 0.9.36
|
||||
*/
|
||||
public void setInOrder(boolean yes) {
|
||||
if (yes == _inOrder)
|
||||
return;
|
||||
_inOrder = yes;
|
||||
if (complete() || metainfo.getFiles() == null)
|
||||
return;
|
||||
if (yes) {
|
||||
List<TorrentFile> sorted = _torrentFiles;
|
||||
int sz = sorted.size();
|
||||
if (sz > 1) {
|
||||
sorted = new ArrayList<TorrentFile>(sorted);
|
||||
Collections.sort(sorted, new FileNameComparator());
|
||||
}
|
||||
for (int i = 0; i < sz; i++) {
|
||||
TorrentFile tf = sorted.get(i);
|
||||
// higher number is higher priority
|
||||
if (tf.priority >= PRIORITY_NORMAL)
|
||||
tf.priority = sz - i;
|
||||
}
|
||||
} else {
|
||||
for (TorrentFile tf : _torrentFiles) {
|
||||
if (tf.priority > PRIORITY_NORMAL)
|
||||
tf.priority = PRIORITY_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort with locale comparator.
|
||||
* (not using TorrentFile.compareTo())
|
||||
* @since 0.9.36
|
||||
*/
|
||||
private static class FileNameComparator implements Comparator<TorrentFile>, Serializable {
|
||||
|
||||
private final Collator c = Collator.getInstance();
|
||||
|
||||
public int compare(TorrentFile l, TorrentFile r) {
|
||||
return c.compare(l.toString(), r.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call setPriority() for all changed files first,
|
||||
* then call this.
|
||||
@ -523,6 +583,25 @@ public class Storage implements Closeable
|
||||
}
|
||||
rv[i] = pri;
|
||||
}
|
||||
if (_inOrder) {
|
||||
// Do a second pass to set the priority of the pieces within each file
|
||||
// this only works because MAX_PIECES * MAX_FILES_PER_TORRENT < Integer.MAX_VALUE
|
||||
// the base file priority
|
||||
int pri = PRIORITY_SKIP;
|
||||
for (int i = 0; i < rv.length; i++) {
|
||||
int val = rv[i];
|
||||
if (val <= PRIORITY_NORMAL)
|
||||
continue;
|
||||
if (val != pri) {
|
||||
pri = val;
|
||||
// new file
|
||||
rv[i] *= MAX_PIECES;
|
||||
} else {
|
||||
// same file, decrement priority from previous piece
|
||||
rv[i] = rv[i-1] - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -544,7 +623,7 @@ public class Storage implements Closeable
|
||||
long rv = 0;
|
||||
final int end = pri.length - 1;
|
||||
for (int i = 0; i <= end; i++) {
|
||||
if (pri[i] <= -9 && !bitfield.get(i)) {
|
||||
if (pri[i] <= PRIORITY_SKIP && !bitfield.get(i)) {
|
||||
rv += (i != end) ? piece_size : metainfo.getPieceLength(i);
|
||||
}
|
||||
}
|
||||
|
@ -2931,7 +2931,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
if (val != null) {
|
||||
String nonce = val[0];
|
||||
if (String.valueOf(_nonce).equals(nonce)) {
|
||||
if (postParams.get("savepri") != null) {
|
||||
if (postParams.get("savepri") != null ||
|
||||
postParams.get("setInOrderEnabled") != null) {
|
||||
savePriorities(snark, postParams);
|
||||
} else if (postParams.get("addComment") != null) {
|
||||
saveComments(snark, postParams);
|
||||
@ -2974,7 +2975,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
|
||||
boolean showStopStart = snark != null;
|
||||
boolean showPriority = snark != null && snark.getStorage() != null && !snark.getStorage().complete() &&
|
||||
Storage storage = snark != null ? snark.getStorage() : null;
|
||||
boolean showPriority = storage != null && !storage.complete() &&
|
||||
r.isDirectory();
|
||||
|
||||
StringBuilder buf=new StringBuilder(4096);
|
||||
@ -3036,13 +3038,13 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
.append(":</b> <a href=\"").append(_contextPath).append('/').append(baseName).append("\">")
|
||||
.append(DataHelper.escapeHTML(fullPath))
|
||||
.append("</a></td></tr>\n");
|
||||
if (snark.getStorage() != null) {
|
||||
if (storage != null) {
|
||||
buf.append("<tr><td>");
|
||||
toThemeImg(buf, "file");
|
||||
buf.append("</td><td><b>")
|
||||
.append(_t("Data location"))
|
||||
.append(":</b> ")
|
||||
.append(DataHelper.escapeHTML(snark.getStorage().getBase().getPath()))
|
||||
.append(DataHelper.escapeHTML(storage.getBase().getPath()))
|
||||
.append("</td></tr>\n");
|
||||
}
|
||||
String hex = I2PSnarkUtil.toHex(snark.getInfoHash());
|
||||
@ -3285,6 +3287,23 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
buf.append("</td></tr>\n");
|
||||
}
|
||||
|
||||
boolean showInOrder = storage != null && !storage.complete() &&
|
||||
meta != null && meta.getFiles() != null && meta.getFiles().size() > 1;
|
||||
if (showInOrder) {
|
||||
buf.append("<tr id=\"torrentOrderControl\"><td colspan=\"2\">");
|
||||
buf.append(_t("Download files in order"));
|
||||
buf.append(":<label><input type=\"checkbox\" class=\"optbox\" name=\"enableInOrder\" id=\"enableInOrder\" ");
|
||||
if (storage.getInOrder())
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append("> ");
|
||||
buf.append(_t("Enable for this torrent"));
|
||||
buf.append("</label>" +
|
||||
"<input type=\"submit\" name=\"setInOrderEnabled\" value=\"");
|
||||
buf.append(_t("Save Preference"));
|
||||
buf.append("\" class=\"accept\">" +
|
||||
"</td></tr>\n");
|
||||
}
|
||||
} else {
|
||||
// snark == null
|
||||
// shouldn't happen
|
||||
@ -3323,7 +3342,6 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
Storage storage = snark != null ? snark.getStorage() : null;
|
||||
List<Sorters.FileAndIndex> fileList = new ArrayList<Sorters.FileAndIndex>(ls.length);
|
||||
// precompute remaining for all files for efficiency
|
||||
long[] remainingArray = (storage != null) ? storage.remaining() : null;
|
||||
@ -3424,6 +3442,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
// DateFormat.MEDIUM);
|
||||
boolean showSaveButton = false;
|
||||
boolean rowEven = true;
|
||||
boolean inOrder = storage != null && storage.getInOrder();
|
||||
for (Sorters.FileAndIndex fai : fileList)
|
||||
{
|
||||
//String encoded = encodePath(ls[i].getName());
|
||||
@ -3447,7 +3466,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
complete = true;
|
||||
//status = toImg("tick") + ' ' + _t("Directory");
|
||||
} else {
|
||||
if (snark == null || snark.getStorage() == null) {
|
||||
if (storage == null) {
|
||||
// Assume complete, perhaps he removed a completed torrent but kept a bookmark
|
||||
complete = true;
|
||||
status = toImg("cancel") + ' ' + _t("Torrent not found?");
|
||||
@ -3527,16 +3546,18 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
if (showPriority) {
|
||||
buf.append("<td class=\"priority\">");
|
||||
if ((!complete) && (!item.isDirectory())) {
|
||||
buf.append("<label class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">" +
|
||||
"\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
|
||||
if (priority > 0)
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append('>')
|
||||
.append(_t("High")).append("</label>");
|
||||
if (!inOrder) {
|
||||
buf.append("<label class=\"priorityHigh\" title=\"").append(_t("Download file at high priority")).append("\">" +
|
||||
"\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
|
||||
if (priority > 0)
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append('>')
|
||||
.append(_t("High")).append("</label>");
|
||||
}
|
||||
|
||||
buf.append("<label class=\"priorityNormal\" title=\"").append(_t("Download file at normal priority")).append("\">" +
|
||||
"\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prinorm\" value=\"0\" name=\"pri.").append(fileIndex).append("\" ");
|
||||
if (priority == 0)
|
||||
if (priority == 0 || (inOrder && priority >= 0))
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append('>')
|
||||
.append(_t("Normal")).append("</label>");
|
||||
@ -3555,9 +3576,12 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
if (showSaveButton) {
|
||||
buf.append("<thead><tr id=\"setPriority\"><th class=\"headerpriority\" colspan=\"5\">" +
|
||||
"<span class=\"script\"><a class=\"control\" id=\"setallhigh\" href=\"javascript:void(null);\" onclick=\"setallhigh();\">")
|
||||
.append(toImg("clock_red")).append(_t("Set all high")).append("</a>\n" +
|
||||
"<a class=\"control\" id=\"setallnorm\" href=\"javascript:void(null);\" onclick=\"setallnorm();\">")
|
||||
"<span class=\"script\">");
|
||||
if (!inOrder) {
|
||||
buf.append("<a class=\"control\" id=\"setallhigh\" href=\"javascript:void(null);\" onclick=\"setallhigh();\">")
|
||||
.append(toImg("clock_red")).append(_t("Set all high")).append("</a>\n");
|
||||
}
|
||||
buf.append("<a class=\"control\" id=\"setallnorm\" href=\"javascript:void(null);\" onclick=\"setallnorm();\">")
|
||||
.append(toImg("clock")).append(_t("Set all normal")).append("</a>\n" +
|
||||
"<a class=\"control\" id=\"setallskip\" href=\"javascript:void(null);\" onclick=\"setallskip();\">")
|
||||
.append(toImg("cancel")).append(_t("Skip all")).append("</a></span>\n" +
|
||||
@ -3926,6 +3950,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
} catch (Throwable t) { t.printStackTrace(); }
|
||||
}
|
||||
}
|
||||
if (postParams.get("setInOrderEnabled") != null)
|
||||
storage.setInOrder(postParams.get("enableInOrder") != null);
|
||||
snark.updatePiecePriorities();
|
||||
_manager.saveTorrentStatus(snark);
|
||||
}
|
||||
|
@ -97,11 +97,10 @@ class ConnectionManager {
|
||||
_connectionHandler = new ConnectionHandler(_context, this, _timer);
|
||||
_tcbShare = new TCBShare(_context, _timer);
|
||||
// PROTO_ANY is for backward compatibility (pre-0.7.1)
|
||||
// TODO change proto to PROTO_STREAMING someday.
|
||||
// Right now we get everything, and rely on Datagram to specify PROTO_UDP.
|
||||
// PacketQueue has sent PROTO_STREAMING since the beginning of mux support (0.7.1)
|
||||
// As of 0.9.1, new option to enforce streaming protocol, off by default
|
||||
// As of 0.9.1, listen on configured port (default 0 = all)
|
||||
// enforce protocol default changed to true in 0.9.36
|
||||
int protocol = defaultOptions.getEnforceProtocol() ? I2PSession.PROTO_STREAMING : I2PSession.PROTO_ANY;
|
||||
_session.addMuxedSessionListener(_messageHandler, protocol, defaultOptions.getLocalPort());
|
||||
_outboundQueue = new PacketQueue(_context, _timer);
|
||||
|
@ -155,9 +155,10 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
|
||||
/**
|
||||
* If PROTO is enforced, we cannot communicate with destinations earlier than version 0.7.1.
|
||||
* Default true as of 0.9.36.
|
||||
* @since 0.9.1
|
||||
*/
|
||||
private static final boolean DEFAULT_ENFORCE_PROTO = false;
|
||||
private static final boolean DEFAULT_ENFORCE_PROTO = true;
|
||||
|
||||
private final int _trend[] = new int[TREND_COUNT];
|
||||
|
||||
@ -523,7 +524,7 @@ class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
|
||||
/**
|
||||
* Do we receive all traffic, or only traffic marked with I2PSession.PROTO_STREAMING (6) ?
|
||||
* Default false.
|
||||
* Default true.
|
||||
* If PROTO is enforced, we cannot communicate with destinations earlier than version 0.7.1
|
||||
* (released March 2009), which is when streaming started sending the PROTO_STREAMING indication.
|
||||
* Set to true if you are running multiple protocols on a single Destination.
|
||||
|
@ -30,10 +30,12 @@ sloccount.report.file=sloccount.sc
|
||||
|
||||
# Building EXEs in x64 Linux requires that 32bit libraries are installed. In Debian,
|
||||
# for example, installing the libc6-i386 package will satisfy this requirement.
|
||||
|
||||
# Uncomment the next line to prevent building EXEs (changing it to false will have no impact)
|
||||
#noExe=true
|
||||
|
||||
# IzPack 5.1.x install dir
|
||||
#izpack5.home=/PATH/TO/IzPack
|
||||
|
||||
# Change this to false if you don't have gettext or you want to prevent it from running during the build
|
||||
require.gettext=true
|
||||
|
||||
|
63
build.xml
63
build.xml
@ -24,6 +24,7 @@
|
||||
<echo message=" installer-osx: build the GUI installer (OSX only)" />
|
||||
<echo message=" installer-windows: build the GUI installer (Windows only)" />
|
||||
<echo message=" installer-nowindows: build the GUI installer (all but Windows)" />
|
||||
<echo message=" installer5, installer5-linux, installer5-nowindows, installer5-windows: use IzPack 5" />
|
||||
<echo message=" osxLauncher: build the Mac OS X router/GUI launcher (OSX only)" />
|
||||
<echo message=" bbLauncher: build the Browser Bundle router launcher" />
|
||||
<echo message=" tarball: tar the full install into i2p.tar.bz2 (extracts to build a new clean install)" />
|
||||
@ -79,7 +80,7 @@
|
||||
<echo message=" devscripts libjetty9-java libtomcat8-java libtaglibs-standard-jstlel-java libgetopt-java" />
|
||||
<echo message=" " />
|
||||
<echo message="The following command will install the additional runtime dependencies:" />
|
||||
<echo message="sudo apt-get install libecj-java geoip-database" />
|
||||
<echo message="sudo apt-get install geoip-database famfamfam-flag-png" />
|
||||
<echo message=" " />
|
||||
<echo message="Once the dependencies are installed, run "ant debian""/>
|
||||
<echo message="to patch the source and build the packages." />
|
||||
@ -1762,18 +1763,36 @@
|
||||
<ant dir="installer/java" target="build" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 4 -->
|
||||
<target name="installer" depends="preppkg, buildProperties, util-list-changes, izpack-patches, buildUtilityJar" >
|
||||
<!--
|
||||
Force 1.5 pack200 output
|
||||
Doesnt work!
|
||||
http://jira.codehaus.org/browse/IZPACK-404
|
||||
http://forums.sun.com/thread.jspa?threadID=773439
|
||||
http://bfo.co.uk/blog/2010/05/13/combining_ant_jar_signatures_and_pack200.html
|
||||
<property name="com.sun.java.util.jar.pack.package.majver" value="150" />
|
||||
<property name="com.sun.java.util.jar.pack.package.minver" value="7" />
|
||||
-->
|
||||
<izpack input="${basedir}/installer/install.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
|
||||
<ant target="installerexe" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 5 -->
|
||||
<target name="ensureIzpack5" >
|
||||
<!-- set if unset -->
|
||||
<property name="izpack5.home" value="${user.home}/IzPack" />
|
||||
<condition property="izpack5.available" >
|
||||
<available file="${izpack5.home}" type="dir" />
|
||||
</condition>
|
||||
<fail message="Error - IzPack 5.1.x must be installed at ${izpack5.home}, or set izpack5.home=/PATH/TO/IzPack in override.properties, or download from http://izpack.org/downloads/ and install" >
|
||||
<condition>
|
||||
<not>
|
||||
<isset property="izpack5.available" />
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<path id="izpack5.lib.path">
|
||||
<fileset dir="${izpack5.home}/lib" includes="*.jar"/>
|
||||
</path>
|
||||
<taskdef name="izpack5"
|
||||
classpathref="izpack5.lib.path"
|
||||
classname="com.izforge.izpack.ant.IzPackTask" />
|
||||
</target>
|
||||
|
||||
<target name="installer5" depends="ensureIzpack5, preppkg, buildProperties, util-list-changes, buildUtilityJar" >
|
||||
<izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
|
||||
<ant target="installerexe" />
|
||||
</target>
|
||||
|
||||
@ -1786,22 +1805,36 @@
|
||||
</target>
|
||||
|
||||
<!-- Custom installers -->
|
||||
<!-- IzPack 4 -->
|
||||
<target name="installer-nowindows" depends="clean, preppkg-nowindows, izpack-patches" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
|
||||
<izpack input="${basedir}/installer/install.xml" output="${basedir}/i2pinstall_${full.version}.jar" installerType="standard" basedir="${basedir}" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 5 -->
|
||||
<target name="installer5-nowindows" depends="ensureIzpack5, clean, preppkg-nowindows" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
|
||||
<izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/i2pinstall_${full.version}.jar" installerType="standard" basedir="${basedir}" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="installer-freebsd" depends="clean, preppkg-freebsd-only, izpack-patches" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
|
||||
<izpack input="${basedir}/installer/install.xml" output="${basedir}/i2pinstall_${full.version}_freebsd-only.jar" installerType="standard" basedir="${basedir}" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 4 -->
|
||||
<target name="installer-linux" depends="clean, preppkg-linux-only, izpack-patches" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
|
||||
<izpack input="${basedir}/installer/install.xml" output="${basedir}/i2pinstall_${full.version}_linux-only.jar" installerType="standard" basedir="${basedir}" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 5 -->
|
||||
<target name="installer5-linux" depends="ensureIzpack5, clean, preppkg-linux-only" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
|
||||
<izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/i2pinstall_${full.version}_linux-only.jar" installerType="standard" basedir="${basedir}" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="installer-osx" depends="clean, checkForIzpack2App, preppkg-osx-only, izpack-patches">
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="lf" />
|
||||
@ -1845,6 +1878,7 @@
|
||||
<delete dir="pkg-temp" includes="eepget i2prouter INSTALL-headless.txt osid postinstall.sh runplain.sh" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 4 -->
|
||||
<target name="installer-windows" depends="clean, preppkg-windows-only, util-list-changes, izpack-patches, buildUtilityJar" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config *.bat *.cmd **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="crlf"/>
|
||||
<izpack input="${basedir}/installer/install.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
|
||||
@ -1853,6 +1887,15 @@
|
||||
<move file="${basedir}/i2pinstall.exe" tofile="${basedir}/i2pinstall_${full.version}_windows.exe" />
|
||||
</target>
|
||||
|
||||
<!-- IzPack 5 -->
|
||||
<target name="installer5-windows" depends="ensureIzpack5, clean, preppkg-windows-only, util-list-changes, buildUtilityJar" >
|
||||
<fixcrlf srcdir="pkg-temp" includes="*.config *.bat *.cmd **/*.xml **/*.properties **/*.txt scripts/*" encoding="utf8" eol="crlf"/>
|
||||
<izpack5 input="${basedir}/installer/install5.xml" output="${basedir}/install.jar" installerType="standard" basedir="${basedir}" />
|
||||
<ant target="installerexe" />
|
||||
<delete file="${basedir}/install.jar" />
|
||||
<move file="${basedir}/i2pinstall.exe" tofile="${basedir}/i2pinstall_${full.version}_windows.exe" />
|
||||
</target>
|
||||
|
||||
<!-- this is broken as installer-xxx targets may delete (or not delete) things in pkg-temp -->
|
||||
<target name="installer-all" depends="installer-freebsd, installer-linux, installer-osx, installer-windows, installer-nowindows, installer" >
|
||||
</target>
|
||||
|
@ -477,6 +477,23 @@ class AMDInfoImpl extends CPUIDCPUInfo implements AMDCPUInfo
|
||||
modelString = "Ryzen model " + model;
|
||||
}
|
||||
break;
|
||||
|
||||
// http://lkml.iu.edu/hypermail/linux/kernel/1806.1/00730.html
|
||||
// untested
|
||||
case 24: {
|
||||
isK6Compatible = true;
|
||||
isK6_2_Compatible = true;
|
||||
isK6_3_Compatible = true;
|
||||
isAthlonCompatible = true;
|
||||
isAthlon64Compatible = true;
|
||||
// Pending testing of the bulldozer jbigi
|
||||
//isPiledriverCompatible = true;
|
||||
//isSteamrollerCompatible = true;
|
||||
//isExcavatorCompatible = true;
|
||||
//isBulldozerCompatible = true;
|
||||
modelString = "Hygon Dhyana model " + model;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return modelString;
|
||||
}
|
||||
|
@ -310,7 +310,8 @@ public class CPUID {
|
||||
return new VIAInfoImpl();
|
||||
if(!isX86)
|
||||
throw new UnknownCPUException("Failed to read CPU information from the system. The CPUID instruction exists on x86 CPUs only.");
|
||||
if(id.equals("AuthenticAMD"))
|
||||
// http://lkml.iu.edu/hypermail/linux/kernel/1806.1/00730.html
|
||||
if(id.equals("AuthenticAMD") || id.equals("HygonGenuine"))
|
||||
return new AMDInfoImpl();
|
||||
if(id.equals("GenuineIntel"))
|
||||
return new IntelInfoImpl();
|
||||
|
@ -2,9 +2,7 @@ package net.i2p.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
@ -22,13 +20,14 @@ import net.i2p.data.ByteArray;
|
||||
Size Max MaxMem From
|
||||
|
||||
1K 32 32K tunnel TrivialPreprocessor
|
||||
*changed to 512 since we disabled resize()
|
||||
1K 512 512K tunnel FragmentHandler
|
||||
1K 512 512K I2NP TunnelDataMessage
|
||||
1K 512 512K tunnel FragmentedMessage
|
||||
|
||||
1730 128 216K streaming MessageOutputStream
|
||||
1572 64 100K UDP InboundMessageState
|
||||
|
||||
2K 64 128K UDP IMS
|
||||
1730 128 216K streaming MessageOutputStream
|
||||
|
||||
4K 32 128K I2PTunnelRunner
|
||||
|
||||
@ -49,7 +48,7 @@ import net.i2p.data.ByteArray;
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public final class ByteCache {
|
||||
public final class ByteCache extends TryCache<ByteArray> {
|
||||
|
||||
//private static final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
|
||||
private static final Map<Integer, ByteCache> _caches = new ConcurrentHashMap<Integer, ByteCache>(16);
|
||||
@ -83,10 +82,13 @@ public final class ByteCache {
|
||||
if (cacheSize * size > MAX_CACHE)
|
||||
cacheSize = MAX_CACHE / size;
|
||||
Integer sz = Integer.valueOf(size);
|
||||
ByteCache cache = _caches.get(sz);
|
||||
if (cache == null) {
|
||||
cache = new ByteCache(cacheSize, size);
|
||||
_caches.put(sz, cache);
|
||||
ByteCache cache;
|
||||
synchronized(_caches) {
|
||||
cache = _caches.get(sz);
|
||||
if (cache == null) {
|
||||
cache = new ByteCache(cacheSize, size);
|
||||
_caches.put(sz, cache);
|
||||
}
|
||||
}
|
||||
cache.resize(cacheSize);
|
||||
//I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class).error("ByteCache size: " + size + " max: " + cacheSize, new Exception("from"));
|
||||
@ -103,109 +105,85 @@ public final class ByteCache {
|
||||
//_log.warn("WARNING: Low memory, clearing byte caches");
|
||||
}
|
||||
|
||||
/** list of available and available entries */
|
||||
private volatile Queue<ByteArray> _available;
|
||||
private int _maxCached;
|
||||
private final int _entrySize;
|
||||
private volatile long _lastOverflow;
|
||||
|
||||
/** do we actually want to cache? Warning - setting to false may NPE, this should be fixed or removed */
|
||||
private static final boolean _cache = true;
|
||||
|
||||
/** how often do we cleanup the cache */
|
||||
private static final int CLEANUP_FREQUENCY = 33*1000;
|
||||
/** if we haven't exceeded the cache size in 2 minutes, cut our cache in half */
|
||||
private static final long EXPIRE_PERIOD = 2*60*1000;
|
||||
|
||||
/** @since 0.9.36 */
|
||||
private static class ByteArrayFactory implements TryCache.ObjectFactory<ByteArray> {
|
||||
private final int sz;
|
||||
|
||||
ByteArrayFactory(int entrySize) {
|
||||
sz = entrySize;
|
||||
}
|
||||
|
||||
public ByteArray newInstance() {
|
||||
byte data[] = new byte[sz];
|
||||
ByteArray rv = new ByteArray(data);
|
||||
rv.setValid(0);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
private ByteCache(int maxCachedEntries, int entrySize) {
|
||||
if (_cache)
|
||||
_available = new LinkedBlockingQueue<ByteArray>(maxCachedEntries);
|
||||
_maxCached = maxCachedEntries;
|
||||
super(new ByteArrayFactory(entrySize), maxCachedEntries);
|
||||
_entrySize = entrySize;
|
||||
_lastOverflow = -1;
|
||||
SimpleTimer2.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + (entrySize % 777)); //stagger
|
||||
int stagger = SystemVersion.isAndroid() ? 0 : (entrySize % 777);
|
||||
SimpleTimer2.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + stagger);
|
||||
I2PAppContext.getGlobalContext().statManager().createRateStat("byteCache.memory." + entrySize, "Memory usage (B)", "Router", new long[] { 10*60*1000 });
|
||||
}
|
||||
|
||||
private void resize(int maxCachedEntries) {
|
||||
if (_maxCached >= maxCachedEntries) return;
|
||||
_maxCached = maxCachedEntries;
|
||||
// make a bigger one, move the cached items over
|
||||
Queue<ByteArray> newLBQ = new LinkedBlockingQueue<ByteArray>(maxCachedEntries);
|
||||
ByteArray ba;
|
||||
while ((ba = _available.poll()) != null)
|
||||
newLBQ.offer(ba);
|
||||
_available = newLBQ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next available structure, either from the cache or a brand new one.
|
||||
* Returned ByteArray will have valid = 0 and offset = 0.
|
||||
* Returned ByteArray may or may not be zero, depends on whether
|
||||
* release(ba) or release(ba, false) was called.
|
||||
* Which is a problem, you should really specify shouldZero on acquire, not release.
|
||||
*/
|
||||
public final ByteArray acquire() {
|
||||
if (_cache) {
|
||||
ByteArray rv = _available.poll();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
}
|
||||
_lastOverflow = System.currentTimeMillis();
|
||||
byte data[] = new byte[_entrySize];
|
||||
ByteArray rv = new ByteArray(data);
|
||||
rv.setValid(0);
|
||||
//rv.setOffset(0);
|
||||
return rv;
|
||||
// disabled since we're now extending TryCache
|
||||
}
|
||||
|
||||
/**
|
||||
* Put this structure back onto the available cache for reuse
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public final void release(ByteArray entry) {
|
||||
release(entry, true);
|
||||
}
|
||||
|
||||
public final void release(ByteArray entry, boolean shouldZero) {
|
||||
if (_cache) {
|
||||
if (entry == null || entry.getData() == null)
|
||||
return;
|
||||
if (entry.getData().length != _entrySize) {
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Bad size", new Exception("I did it"));
|
||||
return;
|
||||
}
|
||||
entry.setValid(0);
|
||||
entry.setOffset(0);
|
||||
|
||||
if (shouldZero)
|
||||
Arrays.fill(entry.getData(), (byte)0x0);
|
||||
_available.offer(entry);
|
||||
if (entry == null || entry.getData() == null)
|
||||
return;
|
||||
if (entry.getData().length != _entrySize) {
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(ByteCache.class);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("Bad size", new Exception("I did it"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear everything (memory pressure)
|
||||
* @since 0.7.14
|
||||
*/
|
||||
private void clear() {
|
||||
_available.clear();
|
||||
entry.setValid(0);
|
||||
entry.setOffset(0);
|
||||
|
||||
if (shouldZero)
|
||||
Arrays.fill(entry.getData(), (byte)0x0);
|
||||
super.release(entry);
|
||||
}
|
||||
|
||||
private class Cleanup implements SimpleTimer.TimedEvent {
|
||||
public void timeReached() {
|
||||
I2PAppContext.getGlobalContext().statManager().addRateData("byteCache.memory." + _entrySize, _entrySize * _available.size(), 0);
|
||||
if (System.currentTimeMillis() - _lastOverflow > EXPIRE_PERIOD) {
|
||||
// we haven't exceeded the cache size in a few minutes, so lets
|
||||
// shrink the cache
|
||||
int toRemove = _available.size() / 2;
|
||||
for (int i = 0; i < toRemove; i++)
|
||||
_available.poll();
|
||||
//if ( (toRemove > 0) && (_log.shouldLog(Log.DEBUG)) )
|
||||
// _log.debug("Removing " + toRemove + " cached entries of size " + _entrySize);
|
||||
int origsz;
|
||||
lock.lock();
|
||||
try {
|
||||
origsz = items.size();
|
||||
if (origsz > 1 && System.currentTimeMillis() - _lastUnderflow > EXPIRE_PERIOD) {
|
||||
// we haven't exceeded the cache size in a few minutes, so lets
|
||||
// shrink the cache
|
||||
int toRemove = origsz / 2;
|
||||
for (int i = 0; i < toRemove; i++) {
|
||||
items.remove(items.size() - 1);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
I2PAppContext.getGlobalContext().statManager().addRateData("byteCache.memory." + _entrySize, _entrySize * origsz);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,6 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* Like ByteCache but works directly with byte arrays, not ByteArrays.
|
||||
@ -19,9 +16,6 @@ public final class SimpleByteCache {
|
||||
|
||||
private static final int DEFAULT_SIZE = 64;
|
||||
|
||||
/** up to this, use ABQ to minimize object churn and for performance; above this, use LBQ for two locks */
|
||||
private static final int MAX_FOR_ABQ = 64;
|
||||
|
||||
/**
|
||||
* Get a cache responsible for arrays of the given size
|
||||
*
|
||||
@ -60,38 +54,32 @@ public final class SimpleByteCache {
|
||||
bc.clear();
|
||||
}
|
||||
|
||||
/** list of available and available entries */
|
||||
private Queue<byte[]> _available;
|
||||
private int _maxCached;
|
||||
private final TryCache<byte[]> _available;
|
||||
private final int _entrySize;
|
||||
|
||||
/** @since 0.9.36 */
|
||||
private static class ByteArrayFactory implements TryCache.ObjectFactory<byte[]> {
|
||||
private final int sz;
|
||||
|
||||
ByteArrayFactory(int entrySize) {
|
||||
sz = entrySize;
|
||||
}
|
||||
|
||||
public byte[] newInstance() {
|
||||
return new byte[sz];
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleByteCache(int maxCachedEntries, int entrySize) {
|
||||
_maxCached = maxCachedEntries;
|
||||
_available = createQueue();
|
||||
_available = new TryCache(new ByteArrayFactory(entrySize), maxCachedEntries);
|
||||
_entrySize = entrySize;
|
||||
}
|
||||
|
||||
private void resize(int maxCachedEntries) {
|
||||
if (_maxCached >= maxCachedEntries) return;
|
||||
_maxCached = maxCachedEntries;
|
||||
// make a bigger one, move the cached items over
|
||||
Queue<byte[]> newLBQ = createQueue();
|
||||
byte[] ba;
|
||||
while ((ba = _available.poll()) != null)
|
||||
newLBQ.offer(ba);
|
||||
_available = newLBQ;
|
||||
// _available is now final, and getInstance() is not used anywhere,
|
||||
// all call sites just use static acquire()
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LBQ or ABQ
|
||||
* @since 0.9.2
|
||||
*/
|
||||
private Queue<byte[]> createQueue() {
|
||||
if (_entrySize <= MAX_FOR_ABQ)
|
||||
return new ArrayBlockingQueue<byte[]>(_maxCached);
|
||||
return new LinkedBlockingQueue<byte[]>(_maxCached);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next available array, either from the cache or a brand new one
|
||||
*/
|
||||
@ -99,14 +87,11 @@ public final class SimpleByteCache {
|
||||
return getInstance(size).acquire();
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the next available array, either from the cache or a brand new one
|
||||
*/
|
||||
private byte[] acquire() {
|
||||
byte[] rv = _available.poll();
|
||||
if (rv == null)
|
||||
rv = new byte[_entrySize];
|
||||
return rv;
|
||||
return _available.acquire();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +111,7 @@ public final class SimpleByteCache {
|
||||
return;
|
||||
// should be safe without this
|
||||
//Arrays.fill(entry, (byte) 0);
|
||||
_available.offer(entry);
|
||||
_available.release(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
* @author zab
|
||||
*
|
||||
* @param <T>
|
||||
* @since 0.9.36
|
||||
*/
|
||||
public class TryCache<T> {
|
||||
|
||||
@ -24,9 +25,10 @@ public class TryCache<T> {
|
||||
}
|
||||
|
||||
private final ObjectFactory<T> factory;
|
||||
private final int capacity;
|
||||
private final List<T> items;
|
||||
private final Lock lock = new ReentrantLock();
|
||||
protected final int capacity;
|
||||
protected final List<T> items;
|
||||
protected final Lock lock = new ReentrantLock();
|
||||
protected long _lastUnderflow;
|
||||
|
||||
/**
|
||||
* @param factory to be used for creating new instances
|
||||
@ -47,6 +49,8 @@ public class TryCache<T> {
|
||||
try {
|
||||
if (!items.isEmpty()) {
|
||||
rv = items.remove(items.size() - 1);
|
||||
} else {
|
||||
_lastUnderflow = System.currentTimeMillis();
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
|
@ -1,3 +1,10 @@
|
||||
2018-07-10 zzz
|
||||
* Installer (ticket #1864):
|
||||
- Fix wrapper selection on Windows 10
|
||||
- Add support for IzPack 5
|
||||
* SSU: Sync/notify improvements (ticket #2260)
|
||||
* Util: Convert more caches to TryCache (ticket #2263)
|
||||
|
||||
2018-07-08 zzz
|
||||
* i2psnark: Add comment icon (ticket #2278)
|
||||
* NTCP2: Avoid possible NPEs (ticket #2286)
|
||||
|
@ -102,6 +102,17 @@
|
||||
<res id="XInfoPanel.info" src="installer/resources/start-i2p.txt" />
|
||||
</resources>
|
||||
|
||||
<dynamicvariables>
|
||||
<variable name="datamodel" value="${SYSTEM_sun_arch_data_model}"/>
|
||||
</dynamicvariables>
|
||||
|
||||
<conditions>
|
||||
<condition type="variable" id="is64bit">
|
||||
<name>datamodel</name>
|
||||
<value>64</value>
|
||||
</condition>
|
||||
</conditions>
|
||||
|
||||
<panels>
|
||||
<panel classname="HelloPanel"/>
|
||||
<panel classname="InfoPanel"/>
|
||||
@ -115,9 +126,9 @@
|
||||
<!--
|
||||
Using the condition this way, the panel is shown on everything *but* Windows.
|
||||
-->
|
||||
<panel classname="XInfoPanel" condition="!izpack.windowsinstall" />
|
||||
<panel classname="SimpleFinishPanel"/>
|
||||
</panels>
|
||||
<panel classname="XInfoPanel" condition="!izpack.windowsinstall" />
|
||||
<panel classname="SimpleFinishPanel"/>
|
||||
</panels>
|
||||
|
||||
<packs>
|
||||
<pack name="Base" required="yes">
|
||||
@ -136,13 +147,6 @@
|
||||
<parsable targetfile="$INSTALL_PATH/runplain.sh" type="shell"> <os family="unix" /> </parsable>
|
||||
<parsable targetfile="$INSTALL_PATH/Start I2P Router.app/Contents/MacOS/i2prouter" type="shell" os="mac" />
|
||||
|
||||
<conditions>
|
||||
<condition type="variable" id="is64bit">
|
||||
<name>SYSTEM_sun_arch_data_model</name>
|
||||
<value>64</value>
|
||||
</condition>
|
||||
</conditions>
|
||||
|
||||
<!-- postinstall stuff for windows -->
|
||||
<!-- Wrapper for 32bit Windows JVM -->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
|
399
installer/install5.xml
Normal file
399
installer/install5.xml
Normal file
@ -0,0 +1,399 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
|
||||
<!--
|
||||
This is for izpack 5.
|
||||
See install.xml for izpack 4.
|
||||
-->
|
||||
<izpack:installation version="5.0"
|
||||
xmlns:izpack="http://izpack.org/schema/installation"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://izpack.org/schema/installation http://izpack.org/schema/5.0/izpack-installation-5.0.xsd">
|
||||
|
||||
<info>
|
||||
<appname>i2p</appname>
|
||||
<appversion>0.9.35</appversion>
|
||||
<authors>
|
||||
<author name="I2P" email="https://geti2p.net/"/>
|
||||
</authors>
|
||||
<url>https://geti2p.net/</url>
|
||||
<javaversion>1.7</javaversion>
|
||||
|
||||
<!-- adding this element will make the installer attempt to launch itself with administrator permissions,
|
||||
but see http://www.nabble.com/Classpath-security-issues-on-Vista-td22456230.html
|
||||
which says it isn't sufficient:
|
||||
|
||||
Just to let you know that I managed to identify and resolve the problem (in
|
||||
case anyone else has it). The default installation directory for Vista is
|
||||
under "Program Files" which is a "special" directory which can only be
|
||||
written to (create sub-directories) by administrators. However, stupid
|
||||
Vista downgrades an administrator to a normal user when the program is run
|
||||
via the application shortcut menu. As you suggested, I added a script which
|
||||
runs ICACLS which resolved the problem, i.e.
|
||||
|
||||
icacls %1 /grant Users:F /T > priv.log
|
||||
|
||||
The command needs to be run as a Process rather than as an executable tag in
|
||||
order to pass $INSTALL_PATH as a parameter.
|
||||
-->
|
||||
<run-privileged condition="izpack.windowsinstall.vista|izpack.windowsinstall.7"/>
|
||||
</info>
|
||||
|
||||
<guiprefs width="590" height="356" resizable="yes">
|
||||
<!--
|
||||
Not in 5.1.2, pick another one
|
||||
https://izpack.atlassian.net/wiki/spaces/IZPACK/pages/491730/GUI+Preferences
|
||||
<laf name="liquid">
|
||||
<os family="unix"/>
|
||||
</laf>
|
||||
-->
|
||||
<!-- full names, not iso3 codes -->
|
||||
<modifier key="langDisplayType" value="native" />
|
||||
</guiprefs>
|
||||
|
||||
<locale>
|
||||
<langpack iso3="eng"/>
|
||||
<langpack iso3="bra"/>
|
||||
<langpack iso3="cat"/>
|
||||
<langpack iso3="ces"/>
|
||||
<langpack iso3="chn"/>
|
||||
<langpack iso3="dan"/>
|
||||
<langpack iso3="deu"/>
|
||||
<langpack iso3="ell"/>
|
||||
<langpack iso3="fin"/>
|
||||
<langpack iso3="fra"/>
|
||||
<langpack iso3="hun"/>
|
||||
<langpack iso3="idn"/>
|
||||
<langpack iso3="ita"/>
|
||||
<langpack iso3="jpn"/>
|
||||
<langpack iso3="kor"/>
|
||||
<langpack iso3="msa"/>
|
||||
<langpack iso3="nld"/>
|
||||
<langpack iso3="nor"/>
|
||||
<langpack iso3="pol"/>
|
||||
<langpack iso3="prt"/>
|
||||
<langpack iso3="ron"/>
|
||||
<langpack iso3="rus"/>
|
||||
<langpack iso3="slk"/>
|
||||
<langpack iso3="spa"/>
|
||||
<langpack iso3="srp"/>
|
||||
<langpack iso3="swe"/>
|
||||
<langpack iso3="tur"/>
|
||||
<langpack iso3="twn"/>
|
||||
<langpack iso3="ukr"/>
|
||||
<!--
|
||||
"WARNING: No locale for:"
|
||||
<langpack iso3="eus"/>
|
||||
<langpack iso3="fa"/>
|
||||
<langpack iso3="glg"/>
|
||||
-->
|
||||
</locale>
|
||||
|
||||
<!--
|
||||
The <os> tag can be used to restrict the inclusion into the uninstaller
|
||||
to a specific operating system family, architecture or version.
|
||||
The inclusion into the installer will be always done.
|
||||
Here's a sample :
|
||||
|
||||
<native type="izpack" name="ShellLink.dll">
|
||||
<os family="windows"/>
|
||||
</native>
|
||||
|
||||
This doesn't appear to be necessary, the dlls don't get put in Uninstaller/uninstaller.jar on linux
|
||||
-->
|
||||
<natives>
|
||||
<native type="izpack" name="ShellLink.dll" />
|
||||
<native type="izpack" name="ShellLink_x64.dll" />
|
||||
<!--
|
||||
https://izpack.atlassian.net/wiki/spaces/IZPACK/pages/491532/Advanced+Features
|
||||
<native type="izpack" name="WinSetupAPI.dll" />
|
||||
<native type="izpack" name="WinSetupAPI_x64.dll" />
|
||||
https://izpack.atlassian.net/wiki/spaces/IZPACK/pages/491676/RegistryInstallerListener+RegistryUninstallerListener
|
||||
<native type="3rdparty" name="COIOSHelper.dll" />
|
||||
<native type="3rdparty" name="COIOSHelper_x64.dll" />
|
||||
-->
|
||||
</natives>
|
||||
|
||||
<resources>
|
||||
<res id="Installer.image" src="installer/resources/i2plogo.png" />
|
||||
<res id="InfoPanel.info" src="installer/resources/readme.license.txt"/>
|
||||
<!-- <res id="ProcessPanel.Spec.xml" src="installer/resources/ProcessPanel.Spec.xml"/> -->
|
||||
<res id="shortcutSpec.xml" src="installer/resources/shortcutSpec.xml" />
|
||||
<res id="XInfoPanel.info" src="installer/resources/start-i2p.txt" />
|
||||
</resources>
|
||||
|
||||
<variables>
|
||||
<!-- desktop shortcuts enabled by default in ShortcutPanel -->
|
||||
<variable name="DesktopShortcutCheckboxEnabled" value="true" />
|
||||
</variables>
|
||||
|
||||
<dynamicvariables>
|
||||
<variable name="datamodel" value="${SYSTEM[sun.arch.data.model]}"/>
|
||||
</dynamicvariables>
|
||||
|
||||
<conditions>
|
||||
<condition type="variable" id="is64bit">
|
||||
<name>datamodel</name>
|
||||
<value>64</value>
|
||||
</condition>
|
||||
</conditions>
|
||||
|
||||
<panels>
|
||||
<panel classname="HelloPanel"/>
|
||||
<panel classname="InfoPanel"/>
|
||||
<panel classname="TargetPanel"/>
|
||||
<!-- In 5.1.2, PacksPanel will NPE at install time if before TargetPanel -->
|
||||
<panel classname="PacksPanel"><os family="windows" /></panel>
|
||||
<panel classname="InstallPanel"/>
|
||||
<!-- In 5.1.2, ShortcutPanel must be after InstallPanel, so the .ico files will be there,
|
||||
unless <lateShortcutInstall/> is set in shorcutSpec.xml.
|
||||
If you don't do this right, the shortcuts won't have our icons.
|
||||
-->
|
||||
<panel classname="ShortcutPanel"><os family="windows" /></panel>
|
||||
<!--
|
||||
Using the condition this way, the panel is shown on everything *but* Windows.
|
||||
Fails in console mode: Installer says:
|
||||
No console mode helper found for class com.izforge.izpack.panels.xinfo.XInfoPanel, panel type will be skipped in console mode installation
|
||||
No automation helper found for class com.izforge.izpack.panels.xinfo.XInfoPanel, panel type will be skipped in automated installation
|
||||
But isn't actually skipped when installing with -console:
|
||||
SEVERE: com.izforge.izpack.api.exception.IzPackException: Console implementation not found for panel: com.izforge.izpack.panels.xinfo.XInfoPanel
|
||||
-->
|
||||
<panel classname="XInfoPanel" condition="!izpack.windowsinstall" />
|
||||
<panel classname="SimpleFinishPanel"/>
|
||||
</panels>
|
||||
|
||||
<packs>
|
||||
<pack name="Base" required="yes">
|
||||
<description>Base installation files</description>
|
||||
<!-- non-jars -->
|
||||
<fileset dir="pkg-temp" excludes="**/*.jar" targetdir="$INSTALL_PATH"/>
|
||||
<!-- pack200 jars -->
|
||||
<fileset dir="pkg-temp" includes="**/*.jar"
|
||||
excludes="lib/commons-logging.jar lib/jasper-compiler.jar lib/jetty-java5-threadpool.jar lib/jetty-sslengine.jar lib/jbigi.jar"
|
||||
targetdir="$INSTALL_PATH">
|
||||
<pack200/>
|
||||
</fileset>
|
||||
<!-- non-pack200 jars -->
|
||||
<fileset dir="pkg-temp"
|
||||
includes="lib/commons-logging.jar lib/jasper-compiler.jar lib/jetty-java5-threadpool.jar lib/jetty-sslengine.jar lib/jbigi.jar"
|
||||
targetdir="$INSTALL_PATH">
|
||||
</fileset>
|
||||
<!--
|
||||
Do variable substitution in these files. See:
|
||||
http://www.javalobby.org/forums/thread.jspa?threadID=15967&tstart=0
|
||||
and the izpack docs for some guidance.
|
||||
-->
|
||||
<parsable targetfile="$INSTALL_PATH/wrapper.config" type="plain" />
|
||||
<parsable targetfile="$INSTALL_PATH/scripts/home.i2p.i2prouter" type="plain"> <os family="unix" /> </parsable>
|
||||
<parsable targetfile="$INSTALL_PATH/i2prouter" type="shell"> <os family="unix" /> </parsable>
|
||||
<parsable targetfile="$INSTALL_PATH/eepget" type="shell"> <os family="unix" /> </parsable>
|
||||
<parsable targetfile="$INSTALL_PATH/eepget.bat" type="shell"><os family="windows" /></parsable>
|
||||
<parsable targetfile="$INSTALL_PATH/runplain.sh" type="shell"> <os family="unix" /> </parsable>
|
||||
<parsable targetfile="$INSTALL_PATH/Start I2P Router.app/Contents/MacOS/i2prouter" type="shell"><os family="mac" /></parsable>
|
||||
|
||||
<!-- postinstall stuff for windows -->
|
||||
<!-- Wrapper for 32bit Windows JVM -->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall"
|
||||
keep="true"
|
||||
failure="warn"
|
||||
condition="!is64bit">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="copy" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper\win32\I2Psvc.exe" />
|
||||
<arg value="$INSTALL_PATH" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall"
|
||||
keep="true"
|
||||
failure="warn"
|
||||
condition="!is64bit">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="copy" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper\win32\wrapper.dll" />
|
||||
<arg value="$INSTALL_PATH\lib" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!-- wrapper for 64bit Windows JVM -->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall"
|
||||
keep="true"
|
||||
failure="warn"
|
||||
condition="is64bit">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="copy" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper\win64\I2Psvc.exe" />
|
||||
<arg value="$INSTALL_PATH" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall"
|
||||
keep="true"
|
||||
failure="warn"
|
||||
condition="is64bit">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="copy" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper\win64\wrapper.dll" />
|
||||
<arg value="$INSTALL_PATH\lib" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!--
|
||||
We still copy the 32 bit version of wrapper.dll (even with a
|
||||
64bit jvm) so that if a 32 bit jvm is installed in the future,
|
||||
nothing breaks.
|
||||
-->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall"
|
||||
keep="true"
|
||||
failure="warn"
|
||||
condition="is64bit">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="copy" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper\win32\wrapper.dll" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper-windows-x86-32.dll" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!-- workaround for bad default path for wrapper.log in Windows. -->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall" keep="true">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="fixwinpaths" />
|
||||
<arg value="$INSTALL_PATH\wrapper.config" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!-- Now we'll get rid of the UNIX-only stuff -->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall" keep="true" failure="warn">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="delete" />
|
||||
<arg value="$INSTALL_PATH\i2prouter" />
|
||||
<arg value="$INSTALL_PATH\install_i2p_service_unix" />
|
||||
<arg value="$INSTALL_PATH\install-headless.txt" />
|
||||
<arg value="$INSTALL_PATH\runplain.sh" />
|
||||
<arg value="$INSTALL_PATH\osid" />
|
||||
<arg value="$INSTALL_PATH\postinstall.sh" />
|
||||
<arg value="$INSTALL_PATH\uninstall_i2p_service_unix" />
|
||||
<arg value="$INSTALL_PATH\lib\wrapper" />
|
||||
<arg value="$INSTALL_PATH\eepget" />
|
||||
<arg value="$INSTALL_PATH/Start I2P Router.app" />
|
||||
<arg value="$INSTALL_PATH/net.i2p.router.plist.template" />
|
||||
<arg value="$INSTALL_PATH/install_i2p_service_osx.command" />
|
||||
<arg value="$INSTALL_PATH/uninstall_i2p_service_osx.command" />
|
||||
<arg value="$INSTALL_PATH/man" />
|
||||
<arg value="$INSTALL_PATH/locale" />
|
||||
<!-- Placeholder for an OSX 'shortcut' to the router console
|
||||
<arg value="$INSTALL_PATH/I2P Router Console.webloc" />
|
||||
-->
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!-- workaround for vista permission problems - see comments above -->
|
||||
<executable targetfile="$INSTALL_PATH/fixperms.bat" type="bin" stage="postinstall" keep="true" failure="warn"
|
||||
condition="!izpack.windowsinstall.xp+!izpack.windowsinstall.2003" >
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="$INSTALL_PATH" />
|
||||
</args>
|
||||
</executable>
|
||||
<!-- else delete it -->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall" keep="true" failure="warn" condition="izpack.windowsinstall.xp|izpack.windowsinstall.2003">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="delete" />
|
||||
<arg value="$INSTALL_PATH\fixperms.bat" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!--
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall" keep="true" failure="warn">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="exec" />
|
||||
<arg value="$INSTALL_PATH" />
|
||||
<arg value="$INSTALL_PATH\I2Psvc.exe" />
|
||||
<arg value="-c" />
|
||||
<arg value="$INSTALL_PATH\wrapper.config" />
|
||||
</args>
|
||||
</executable>
|
||||
-->
|
||||
|
||||
<!--
|
||||
and now we delete the installer utility jar.
|
||||
I moved this out of installer/ because the directory
|
||||
couldn't be deleted while the jar was active and would
|
||||
remain on the system.
|
||||
|
||||
This, however, works fine.
|
||||
-->
|
||||
<executable targetfile="$INSTALL_PATH/utility.jar"
|
||||
type="jar"
|
||||
class="net.i2p.installer.Main"
|
||||
stage="postinstall" keep="false" failure="warn">
|
||||
<os family="windows" />
|
||||
<args>
|
||||
<arg value="delete" />
|
||||
<arg value="$INSTALL_PATH/utility.jar" />
|
||||
</args>
|
||||
</executable>
|
||||
|
||||
<!-- postinstall stuff for *nix -->
|
||||
<!-- stage=never means chmod a+x -->
|
||||
<executable targetfile="$INSTALL_PATH/postinstall.sh" type="bin" stage="never" keep="true" failure="warn"><os family="unix" /></executable>
|
||||
<executable targetfile="$INSTALL_PATH/postinstall.sh" type="bin" stage="postinstall" keep="true" failure="warn"><os family="unix" />
|
||||
<args><arg value="$INSTALL_PATH" /></args></executable>
|
||||
<!--
|
||||
Removal of the I2P service in Windows should be done in the base pack
|
||||
so that even if a user installed the service manually it will still be
|
||||
removed when uninstalling.
|
||||
-->
|
||||
<executable targetfile="$INSTALL_PATH/uninstall_i2p_service_winnt.bat" stage="uninstall"><os family="windows" /></executable>
|
||||
</pack>
|
||||
|
||||
<!-- to disable by default, add preselected="no" -->
|
||||
<pack name="Windows Service" required="no" preselected="no">
|
||||
<description>Automatically start I2P in the background</description>
|
||||
<os family="windows" />
|
||||
<executable targetfile="$INSTALL_PATH/set_config_dir_for_nt_service.bat" stage="postinstall" failure="warn" keep="true" />
|
||||
<executable targetfile="$INSTALL_PATH/install_i2p_service_winnt.bat" stage="postinstall" failure="warn" keep="true" />
|
||||
<executable targetfile="$INSTALL_PATH/I2Psvc.exe" stage="postinstall" failure="warn" keep="true">
|
||||
<args>
|
||||
<arg value="-t" />
|
||||
<arg value="$INSTALL_PATH\wrapper.config" />
|
||||
</args>
|
||||
</executable>
|
||||
</pack>
|
||||
</packs>
|
||||
|
||||
</izpack:installation>
|
@ -106,6 +106,7 @@
|
||||
6. Change revision in:
|
||||
- `history.txt`
|
||||
- `installer/install.xml`
|
||||
- `installer/install5.xml`
|
||||
- `core/java/src/net/i2p/CoreVersion.java`
|
||||
- `router/java/src/net/i2p/router/RouterVersion.java`
|
||||
- (change to BUILD = 0 and EXTRA = "")
|
||||
|
@ -104,7 +104,7 @@ fi
|
||||
|
||||
chmod 755 ./eepget
|
||||
rm -rf ./icons ./lib/wrapper
|
||||
rm -f ./lib/*.dll /*.bat ./*.cmd ./*.exe ./utility.jar
|
||||
rm -f ./lib/*.dll ./*.bat ./*.cmd ./*.exe ./utility.jar
|
||||
|
||||
if [ ! `echo $HOST_OS |grep osx` ]; then
|
||||
rm -rf ./Start\ I2P\ Router.app
|
||||
|
@ -882,14 +882,6 @@ public class HandshakeState implements Destroyable {
|
||||
return symmetric.getChainingKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P for getting current hash for siphash calculation
|
||||
* @return NOT a copy, do not modify
|
||||
*/
|
||||
public byte[] getHash() {
|
||||
return symmetric.getHandshakeHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P debug
|
||||
*/
|
||||
|
@ -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 = 7;
|
||||
public final static long BUILD = 10;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
@ -343,8 +343,6 @@ class NTCP2Payload {
|
||||
* Big endian.
|
||||
* Same as DataHelper.fromLong(src, offset, 8) but allows negative result
|
||||
*
|
||||
* Package private for NTCP2Payload.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
* @since 0.9.36
|
||||
*/
|
||||
|
@ -442,7 +442,7 @@ class OutboundNTCP2State implements EstablishState {
|
||||
tk = new SessionKey(temp_key);
|
||||
byte[] ask_master = doHMAC(ctx, tk, ASK);
|
||||
byte[] tmp = new byte[32 + SIPHASH.length];
|
||||
byte[] hash = state.getHash();
|
||||
byte[] hash = state.getHandshakeHash();
|
||||
System.arraycopy(hash, 0, tmp, 0, 32);
|
||||
System.arraycopy(SIPHASH, 0, tmp, 32, SIPHASH.length);
|
||||
tk = new SessionKey(ask_master);
|
||||
|
@ -260,7 +260,7 @@ class InboundMessageFragments /*implements UDPTransport.PartialACKSource */{
|
||||
// By calling add(), this also is a failsafe against possible
|
||||
// races in OutboundMessageFragments.
|
||||
if (newAck && from.getOutboundMessageCount() > 0)
|
||||
_outbound.add(from);
|
||||
_outbound.add(from, 0);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -51,11 +51,6 @@ class OutboundMessageFragments {
|
||||
*/
|
||||
private Iterator<PeerState> _iterator;
|
||||
|
||||
/**
|
||||
* Avoid sync in add() if possible (not 100% reliable)
|
||||
*/
|
||||
private volatile boolean _isWaiting;
|
||||
|
||||
private volatile boolean _alive;
|
||||
private final PacketBuilder _builder;
|
||||
|
||||
@ -104,7 +99,7 @@ class OutboundMessageFragments {
|
||||
_alive = false;
|
||||
_activePeers.clear();
|
||||
synchronized (_activePeers) {
|
||||
_activePeers.notifyAll();
|
||||
_activePeers.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +160,7 @@ class OutboundMessageFragments {
|
||||
// will throw IAE if peer == null
|
||||
OutboundMessageState state = new OutboundMessageState(_context, msg, peer);
|
||||
peer.add(state);
|
||||
add(peer);
|
||||
add(peer, state.fragmentSize(0));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
_transport.failed(msg, "Peer disconnected quickly");
|
||||
return;
|
||||
@ -182,7 +177,7 @@ class OutboundMessageFragments {
|
||||
if (peer == null)
|
||||
throw new RuntimeException("null peer for " + state);
|
||||
peer.add(state);
|
||||
add(peer);
|
||||
add(peer, state.fragmentSize(0));
|
||||
//_context.statManager().addRateData("udp.outboundActiveCount", active, 0);
|
||||
}
|
||||
|
||||
@ -195,10 +190,15 @@ class OutboundMessageFragments {
|
||||
if (peer == null)
|
||||
throw new RuntimeException("null peer");
|
||||
int sz = states.size();
|
||||
int min = peer.fragmentSize();
|
||||
for (int i = 0; i < sz; i++) {
|
||||
peer.add(states.get(i));
|
||||
OutboundMessageState state = states.get(i);
|
||||
peer.add(state);
|
||||
int fsz = state.fragmentSize(0);
|
||||
if (fsz < min)
|
||||
min = fsz;
|
||||
}
|
||||
add(peer);
|
||||
add(peer, min);
|
||||
//_context.statManager().addRateData("udp.outboundActiveCount", active, 0);
|
||||
}
|
||||
|
||||
@ -211,10 +211,10 @@ class OutboundMessageFragments {
|
||||
* There are larger chances of adding the PeerState "behind" where
|
||||
* the iterator is now... but these issues are the same as before concurrentification.
|
||||
*
|
||||
* @param the minimum size we can send, or 0 to always notify
|
||||
* @since 0.8.9
|
||||
*/
|
||||
public void add(PeerState peer) {
|
||||
boolean wasEmpty = _activePeers.isEmpty();
|
||||
public void add(PeerState peer, int size) {
|
||||
boolean added = _activePeers.add(peer);
|
||||
if (added) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -229,9 +229,9 @@ class OutboundMessageFragments {
|
||||
// no, this doesn't always work.
|
||||
// Also note that the iterator in getNextVolley may have alreay passed us,
|
||||
// or not reflect the addition.
|
||||
if (_isWaiting || wasEmpty) {
|
||||
if (added || size <= 0 || peer.getSendWindowBytesRemaining() >= size) {
|
||||
synchronized (_activePeers) {
|
||||
_activePeers.notifyAll();
|
||||
_activePeers.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,7 +321,6 @@ class OutboundMessageFragments {
|
||||
// if we've gone all the way through the loop, wait
|
||||
// ... unless nextSendDelay says we have more ready now
|
||||
if (states == null && peersProcessed >= _activePeers.size() && nextSendDelay > 0) {
|
||||
_isWaiting = true;
|
||||
peersProcessed = 0;
|
||||
// why? we do this in the loop one at a time
|
||||
//finishMessages();
|
||||
@ -341,7 +340,6 @@ class OutboundMessageFragments {
|
||||
_log.debug("Woken up while waiting");
|
||||
}
|
||||
}
|
||||
_isWaiting = false;
|
||||
//} else {
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("dont wait: alive=" + _alive + " state = " + state);
|
||||
|
@ -34,7 +34,7 @@ class TrivialPreprocessor implements TunnelGateway.QueuePreprocessor {
|
||||
* (since ByteCache only maintains once instance for each size)
|
||||
* Used in BatchedPreprocessor; see add'l comments there
|
||||
*/
|
||||
protected static final ByteCache _dataCache = ByteCache.getInstance(32, PREPROCESSED_SIZE);
|
||||
protected static final ByteCache _dataCache = ByteCache.getInstance(512, PREPROCESSED_SIZE);
|
||||
|
||||
public TrivialPreprocessor(RouterContext ctx) {
|
||||
_context = ctx;
|
||||
|
Reference in New Issue
Block a user