merge of '3a7591d75dacb165b1b1d26c6bdd94184076fb03'
and 'ba02b6daf2d660339ff05cfe0479344391e6e34f'
@@ -517,7 +517,6 @@ public class MetaInfo
|
||||
* @since 0.9.1
|
||||
*/
|
||||
boolean checkPiece(PartialPiece pp) {
|
||||
MessageDigest sha1 = SHA1.getInstance();
|
||||
int piece = pp.getPiece();
|
||||
byte[] hash;
|
||||
try {
|
||||
|
||||
@@ -170,8 +170,7 @@ class PeerAcceptor
|
||||
if (b != PROTO[i])
|
||||
throw new IOException("Bad protocol 0x" + Integer.toHexString(b) + " at byte " + i);
|
||||
}
|
||||
if (in.skip(8) != 8)
|
||||
throw new IOException("EOF before hash");
|
||||
DataHelper.skip(in, 8);
|
||||
byte buf[] = new byte[20];
|
||||
int read = DataHelper.read(in, buf);
|
||||
if (read != buf.length)
|
||||
|
||||
@@ -232,7 +232,7 @@ public class Snark
|
||||
private byte[] id;
|
||||
private final byte[] infoHash;
|
||||
private String additionalTrackerURL;
|
||||
private final I2PSnarkUtil _util;
|
||||
protected final I2PSnarkUtil _util;
|
||||
private final Log _log;
|
||||
private final PeerCoordinatorSet _peerCoordinatorSet;
|
||||
private volatile String trackerProblems;
|
||||
|
||||
@@ -531,7 +531,7 @@ public class SnarkManager implements CompleteListener {
|
||||
_util.setStartupDelay(minutes);
|
||||
changed = true;
|
||||
_config.setProperty(PROP_STARTUP_DELAY, Integer.toString(minutes));
|
||||
addMessage(_("Startup delay changed to {0}", DataHelper.formatDuration2(minutes * 60 * 1000)));
|
||||
addMessage(_("Startup delay changed to {0}", DataHelper.formatDuration2(minutes * (60L * 1000))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,7 +754,7 @@ public class SnarkManager implements CompleteListener {
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public void saveOpenTrackers(List<String> ot) {
|
||||
String val = setListConfig(PROP_OPENTRACKERS, ot);
|
||||
setListConfig(PROP_OPENTRACKERS, ot);
|
||||
if (ot == null)
|
||||
ot = Collections.singletonList(I2PSnarkUtil.DEFAULT_OPENTRACKERS);
|
||||
_util.setOpenTrackers(ot);
|
||||
@@ -1489,7 +1489,7 @@ public class SnarkManager implements CompleteListener {
|
||||
private class DirMonitor implements Runnable {
|
||||
public void run() {
|
||||
// don't bother delaying if auto start is false
|
||||
long delay = 60 * 1000 * getStartupDelayMinutes();
|
||||
long delay = (60L * 1000) * getStartupDelayMinutes();
|
||||
if (delay > 0 && shouldAutoStart()) {
|
||||
addMessage(_("Adding torrents in {0}", DataHelper.formatDuration2(delay)));
|
||||
try { Thread.sleep(delay); } catch (InterruptedException ie) {}
|
||||
|
||||
@@ -473,6 +473,9 @@ public class TrackerClient implements Runnable {
|
||||
{
|
||||
long uploaded = coordinator.getUploaded();
|
||||
long downloaded = coordinator.getDownloaded();
|
||||
long len = snark.getTotalLength();
|
||||
if (len > 0 && downloaded > len)
|
||||
downloaded = len;
|
||||
left = coordinator.getLeft();
|
||||
String event;
|
||||
if (!tr.started) {
|
||||
@@ -508,6 +511,7 @@ public class TrackerClient implements Runnable {
|
||||
info.getSeedCount() > 100 &&
|
||||
coordinator.getPeerCount() <= 0 &&
|
||||
_util.getContext().clock().now() > _startedOn + 2*60*60*1000 &&
|
||||
snark.getTotalLength() > 0 &&
|
||||
uploaded >= 2 * snark.getTotalLength()) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Auto stopping " + snark.getBaseName());
|
||||
@@ -715,6 +719,9 @@ public class TrackerClient implements Runnable {
|
||||
_log.debug("Running unannounce " + _threadName + " to " + tr.announce);
|
||||
long uploaded = coordinator.getUploaded();
|
||||
long downloaded = coordinator.getDownloaded();
|
||||
long len = snark.getTotalLength();
|
||||
if (len > 0 && downloaded > len)
|
||||
downloaded = len;
|
||||
long left = coordinator.getLeft();
|
||||
try
|
||||
{
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BDecoder
|
||||
private int indicator = 0;
|
||||
|
||||
// Used for ugly hack to get SHA hash over the metainfo info map
|
||||
private final String special_map = "info";
|
||||
private static final String special_map = "info";
|
||||
private boolean in_special_map = false;
|
||||
/** creation deferred until we encounter the special map, to make processing of announce replies more efficient */
|
||||
private MessageDigest sha_digest;
|
||||
|
||||
@@ -36,6 +36,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SystemVersion;
|
||||
@@ -469,7 +470,7 @@ class BasicServlet extends HttpServlet
|
||||
{
|
||||
String cpath = getServletContext().getContextPath();
|
||||
// this won't work if we aren't at top level
|
||||
String cname = cpath == "" ? "i2psnark" : cpath.substring(1).replace("/", "_");
|
||||
String cname = "".equals(cpath) ? "i2psnark" : cpath.substring(1).replace("/", "_");
|
||||
return (new File(_context.getBaseDir(), "webapps/" + cname + ".war")).lastModified();
|
||||
}
|
||||
|
||||
@@ -578,7 +579,7 @@ class BasicServlet extends HttpServlet
|
||||
byte[] buf = ba.getData();
|
||||
try {
|
||||
if (skip > 0)
|
||||
in.skip(skip);
|
||||
DataHelper.skip(in, skip);
|
||||
int read = 0;
|
||||
long tot = 0;
|
||||
boolean done = false;
|
||||
|
||||
@@ -198,7 +198,7 @@ public class FetchAndAdd extends Snark implements EepGet.StatusListener, Runnabl
|
||||
//_total = -1;
|
||||
_transferred = 0;
|
||||
_failCause = null;
|
||||
_started = _ctx.clock().now();
|
||||
_started = _util.getContext().clock().now();
|
||||
_isRunning = true;
|
||||
_active = false;
|
||||
_thread = new I2PAppThread(this, "Torrent File EepGet", true);
|
||||
|
||||
@@ -2548,7 +2548,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
if (showPriority) {
|
||||
buf.append("<td class=\"priority\">");
|
||||
File f = item;
|
||||
if ((!complete) && (!item.isDirectory()) && f != null) {
|
||||
if ((!complete) && (!item.isDirectory())) {
|
||||
int pri = snark.getStorage().getPriority(f.getCanonicalPath());
|
||||
buf.append("<input type=\"radio\" value=\"5\" name=\"pri.").append(f.getCanonicalPath()).append("\" ");
|
||||
if (pri > 0)
|
||||
|
||||
@@ -71,7 +71,7 @@ abstract class IRCFilter {
|
||||
|
||||
// Allow numerical responses
|
||||
try {
|
||||
new Integer(command);
|
||||
Integer.parseInt(command);
|
||||
return s;
|
||||
} catch(NumberFormatException nfe){}
|
||||
|
||||
|
||||
@@ -104,19 +104,20 @@ public class SOCKS4aServer extends SOCKSServer {
|
||||
throw new SOCKSException("Invalid port number in request");
|
||||
}
|
||||
|
||||
connHostName = new String("");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
boolean alreadyWarned = false;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int octet = in.readByte() & 0xff;
|
||||
connHostName += Integer.toString(octet);
|
||||
builder.append(Integer.toString(octet));
|
||||
if (i != 3) {
|
||||
connHostName += ".";
|
||||
builder.append(".");
|
||||
if (octet != 0 && !alreadyWarned) {
|
||||
_log.warn("IPV4 address type in request: " + connHostName + ". Is your client secure?");
|
||||
alreadyWarned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
connHostName = builder.toString();
|
||||
|
||||
// Check if the requested IP should be mapped to a domain name
|
||||
String mappedDomainName = getMappedDomainNameForIP(connHostName);
|
||||
|
||||
@@ -198,14 +198,16 @@ public class SOCKS5Server extends SOCKSServer {
|
||||
addressType = in.readUnsignedByte();
|
||||
switch (addressType) {
|
||||
case AddressType.IPV4:
|
||||
connHostName = new String("");
|
||||
//connHostName = new String();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int octet = in.readUnsignedByte();
|
||||
connHostName += Integer.toString(octet);
|
||||
builder.append(Integer.toString(octet));
|
||||
if (i != 3) {
|
||||
connHostName += ".";
|
||||
builder.append(".");
|
||||
}
|
||||
}
|
||||
connHostName = builder.toString();
|
||||
// Check if the requested IP should be mapped to a domain name
|
||||
String mappedDomainName = getMappedDomainNameForIP(connHostName);
|
||||
if (mappedDomainName != null) {
|
||||
|
||||
@@ -273,8 +273,6 @@ public class IndexBean {
|
||||
TunnelController cur = getController(_tunnel);
|
||||
|
||||
Properties config = getConfig();
|
||||
if (config == null)
|
||||
return "Invalid params";
|
||||
|
||||
if (cur == null) {
|
||||
// creating new
|
||||
@@ -970,8 +968,6 @@ public class IndexBean {
|
||||
|
||||
TunnelController tun = getController(_tunnel);
|
||||
Properties config = getConfig();
|
||||
if (config == null)
|
||||
return "Invalid params";
|
||||
if (tun == null) {
|
||||
// creating new
|
||||
tun = new TunnelController(config, "", true);
|
||||
@@ -1038,8 +1034,6 @@ public class IndexBean {
|
||||
private String generateNewEncryptionKey() {
|
||||
TunnelController tun = getController(_tunnel);
|
||||
Properties config = getConfig();
|
||||
if (config == null)
|
||||
return "Invalid params";
|
||||
if (tun == null) {
|
||||
// creating new
|
||||
tun = new TunnelController(config, "", true);
|
||||
|
||||
@@ -238,8 +238,8 @@ public class ConfigNetHelper extends HelperBase {
|
||||
return kbytesToBits(getShareBandwidth());
|
||||
}
|
||||
private String kbytesToBits(int kbytes) {
|
||||
return DataHelper.formatSize(kbytes * 8 * 1024) + ' ' + _("bits per second") +
|
||||
' ' + _("or {0} bytes per month maximum", DataHelper.formatSize(kbytes * 1024l * 60 * 60 * 24 * 31));
|
||||
return DataHelper.formatSize(kbytes * (8 * 1024L)) + ' ' + _("bits per second") +
|
||||
' ' + _("or {0} bytes per month maximum", DataHelper.formatSize(kbytes * (1024L * 60 * 60 * 24 * 31)));
|
||||
}
|
||||
public String getInboundBurstRate() {
|
||||
return "" + _context.bandwidthLimiter().getInboundBurstKBytesPerSecond();
|
||||
|
||||
@@ -38,28 +38,28 @@ public class HomeHelper extends HelperBase {
|
||||
static final String DEFAULT_FAVORITES =
|
||||
_x("Bug Reports") + S + _x("Bug tracker") + S + "http://trac.i2p2.i2p/report/1" + S + I + "bug.png" + S +
|
||||
//"colombo-bt.i2p" + S + _x("The Italian Bittorrent Resource") + S + "http://colombo-bt.i2p/" + S + I + "colomboicon.png" + S +
|
||||
_x("Dev Forum") + S + _x("Development forum") + S + "http://zzz.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("diftracker") + S + _x("Bittorrent tracker") + S + "http://diftracker.i2p/" + S + I + "eepsite.png" + S +
|
||||
"echelon.i2p" + S + _x("I2P Applications") + S + "http://echelon.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Dev Forum") + S + _x("Development forum") + S + "http://zzz.i2p/" + S + I + "group_gear.png" + S +
|
||||
_x("diftracker") + S + _x("Bittorrent tracker") + S + "http://diftracker.i2p/" + S + I + "magnet.png" + S +
|
||||
"echelon.i2p" + S + _x("I2P Applications") + S + "http://echelon.i2p/" + S + I + "box_open.png" + S +
|
||||
_x("FAQ") + S + _x("Frequently Asked Questions") + S + "http://www.i2p2.i2p/faq" + S + I + "question.png" + S +
|
||||
_x("Forum") + S + _x("Community forum") + S + "http://forum.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Forum") + S + _x("Community forum") + S + "http://forum.i2p/" + S + I + "group.png" + S +
|
||||
_x("Anonymous Git Hosting") + S + _x("A public anonymous Git hosting site - supports pulling via Git and HTTP and pushing via SSH") + S + "http://git.repo.i2p/" + S + I + "git-logo.png" + S +
|
||||
"Ident " + _x("Microblog") + S + _x("Your premier microblogging service on I2P") + S + "http://id3nt.i2p/" + S + I + "ident_icon_blue.png" + S +
|
||||
_x("Javadocs") + S + _x("Technical documentation") + S + "http://i2p-javadocs.i2p/" + S + I + "education.png" + S +
|
||||
//_x("Key Server") + S + _x("OpenPGP Keyserver") + S + "http://keys.i2p/" + S + I + "education.png" + S +
|
||||
"killyourtv.i2p" + S + _x("Debian and Tahoe-LAFS repositories") + S + "http://killyourtv.i2p/" + S + I + "eepsite.png" + S +
|
||||
"killyourtv.i2p" + S + _x("Debian and Tahoe-LAFS repositories") + S + "http://killyourtv.i2p/" + S + I + "television_delete.png" + S +
|
||||
_x("Free Web Hosting") + S + _x("Free eepsite hosting with PHP and MySQL") + S + "http://open4you.i2p/" + S + I + "open4you-logo.png" + S +
|
||||
_x("Pastebin") + S + _x("I2P Pastebin") + S + "http://pastethis.i2p/" + S + I + "eepsite.png" + S +
|
||||
"Planet I2P" + S + _x("I2P News") + S + "http://planet.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Pastebin") + S + _x("I2P Pastebin") + S + "http://pastethis.i2p/" + S + I + "paste_plain.png" + S +
|
||||
"Planet I2P" + S + _x("I2P News") + S + "http://planet.i2p/" + S + I + "world.png" + S +
|
||||
_x("Plugins") + S + _x("Add-on directory") + S + "http://plugins.i2p/" + S + I + "plugin.png" + S +
|
||||
_x("Postman's Tracker") + S + _x("Bittorrent tracker") + S + "http://tracker2.postman.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Postman's Tracker") + S + _x("Bittorrent tracker") + S + "http://tracker2.postman.i2p/" + S + I + "magnet.png" + S +
|
||||
_x("Project Website") + S + _x("I2P home page") + S + "http://www.i2p2.i2p/" + S + I + "info_rhombus.png" + S +
|
||||
"Salt" + S + "salt.i2p" + S + "http://salt.i2p/" + S + I + "salt_console.png" + S +
|
||||
"stats.i2p" + S + _x("I2P Network Statistics") + S + "http://stats.i2p/cgi-bin/dashboard.cgi" + S + I + "chart_line.png" + S +
|
||||
_x("Technical Docs") + S + _x("Technical documentation") + S + "http://www.i2p2.i2p/how" + S + I + "education.png" + S +
|
||||
_x("Trac Wiki") + S + S + "http://trac.i2p2.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Ugha's Wiki") + S + S + "http://ugha.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Sponge's main site") + S + _x("Seedless and the Robert BitTorrent applications") + S + "http://sponge.i2p/" + S + I + "eepsite.png" + S +
|
||||
_x("Trac Wiki") + S + S + "http://trac.i2p2.i2p/" + S + I + "billiard_marker.png" + S +
|
||||
_x("Ugha's Wiki") + S + S + "http://ugha.i2p/" + S + I + "billiard_marker.png" + S +
|
||||
_x("Sponge's main site") + S + _x("Seedless and the Robert BitTorrent applications") + S + "http://sponge.i2p/" + S + I + "user_astronaut.png" + S +
|
||||
"";
|
||||
|
||||
|
||||
|
||||
@@ -93,7 +93,8 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
|
||||
if (doSend) {
|
||||
PacketLocal packet = send(buf, off, size);
|
||||
if (packet == null) return _dummyStatus;
|
||||
// this shouldn't be null
|
||||
//if (packet == null) return _dummyStatus;
|
||||
|
||||
//dont wait for non-acks
|
||||
if ( (packet.getSequenceNum() > 0) || (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) )
|
||||
@@ -115,7 +116,7 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
* @param buf data to be sent - may be null
|
||||
* @param off offset into the buffer to start writing from
|
||||
* @param size how many bytes of the buffer to write (may be 0)
|
||||
* @return the packet sent, or null if the connection died
|
||||
* @return the packet sent
|
||||
*/
|
||||
public PacketLocal send(byte buf[], int off, int size) {
|
||||
return send(buf, off, size, false);
|
||||
|
||||
@@ -201,7 +201,7 @@ class ConnectionPacketHandler {
|
||||
final long lastSendTime = con.getLastSendTime();
|
||||
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(String.format("%s congestion.. dup packet %s ackDelay %d lastSend %d ago",
|
||||
_log.warn(String.format("%s congestion.. dup packet %s ackDelay %d lastSend %s ago",
|
||||
con, packet, ackDelay, DataHelper.formatDuration(now - lastSendTime)));
|
||||
|
||||
final long nextSendTime = lastSendTime + ackDelay;
|
||||
|
||||
@@ -238,10 +238,7 @@ public class PcapWriter {
|
||||
seq = pkt.getSequenceNum();
|
||||
long acked = 0;
|
||||
if (con != null) {
|
||||
if (isInbound)
|
||||
acked = getLowestAckedThrough(pkt, con);
|
||||
else
|
||||
acked = getLowestAckedThrough(pkt, con);
|
||||
acked = getLowestAckedThrough(pkt, con);
|
||||
}
|
||||
DataHelper.writeLong(_fos, 4, pkt.getSequenceNum());
|
||||
DataHelper.writeLong(_fos, 4, acked);
|
||||
|
||||
@@ -435,11 +435,11 @@ public class MultiPartRequest
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private class Part
|
||||
private static class Part
|
||||
{
|
||||
String _name=null;
|
||||
String _filename=null;
|
||||
String _name;
|
||||
String _filename;
|
||||
Hashtable _headers= new Hashtable(10);
|
||||
byte[] _data=null;
|
||||
byte[] _data;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,30 +14,30 @@ abstract class CPUIDCPUInfo
|
||||
}
|
||||
public boolean hasMMX()
|
||||
{
|
||||
return (CPUID.getEDXCPUFlags() & 0x800000) >0; //EDX Bit 23
|
||||
return (CPUID.getEDXCPUFlags() & 0x800000) != 0; //EDX Bit 23
|
||||
}
|
||||
public boolean hasSSE(){
|
||||
return (CPUID.getEDXCPUFlags() & 0x2000000) >0; //EDX Bit 25
|
||||
return (CPUID.getEDXCPUFlags() & 0x2000000) != 0; //EDX Bit 25
|
||||
}
|
||||
public boolean hasSSE2()
|
||||
{
|
||||
return (CPUID.getEDXCPUFlags() & 0x4000000) >0; //EDX Bit 26
|
||||
return (CPUID.getEDXCPUFlags() & 0x4000000) != 0; //EDX Bit 26
|
||||
}
|
||||
public boolean hasSSE3()
|
||||
{
|
||||
return (CPUID.getEDXCPUFlags() & 0x1) >0; //ECX Bit 0
|
||||
return (CPUID.getEDXCPUFlags() & 0x1) != 0; //ECX Bit 0
|
||||
}
|
||||
public boolean hasSSE41()
|
||||
{
|
||||
return (CPUID.getEDXCPUFlags() & 0x80000) >0; //ECX Bit 19
|
||||
return (CPUID.getEDXCPUFlags() & 0x80000) != 0; //ECX Bit 19
|
||||
}
|
||||
public boolean hasSSE42()
|
||||
{
|
||||
return (CPUID.getEDXCPUFlags() & 0x100000) >0; //ECX Bit 20
|
||||
return (CPUID.getEDXCPUFlags() & 0x100000) != 0; //ECX Bit 20
|
||||
}
|
||||
public boolean hasSSE4A()
|
||||
{
|
||||
return (CPUID.getExtendedECXCPUFlags() & 0x40) >0; //Extended ECX Bit 6
|
||||
return (CPUID.getExtendedECXCPUFlags() & 0x40) != 0; //Extended ECX Bit 6
|
||||
}
|
||||
|
||||
public abstract boolean hasX64();
|
||||
|
||||
@@ -598,7 +598,6 @@ public class DSAEngine {
|
||||
private Signature altSignRaw(SimpleDataStructure hash, SigningPrivateKey privateKey) throws GeneralSecurityException {
|
||||
SigType type = privateKey.getType();
|
||||
String algo = getRawAlgo(type);
|
||||
java.security.Signature jsig = java.security.Signature.getInstance(algo);
|
||||
PrivateKey privKey = SigUtil.toJavaKey(privateKey);
|
||||
return altSignRaw(algo, hash, privKey, type);
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ class SigUtil {
|
||||
throws GeneralSecurityException {
|
||||
SigType type = pk.getType();
|
||||
int len = type.getPubkeyLen();
|
||||
int sublen = len / 2;
|
||||
byte[] b = pk.getData();
|
||||
BigInteger s = new NativeBigInteger(1, b);
|
||||
// see ECConstants re: casting
|
||||
|
||||
@@ -474,9 +474,7 @@ riCe6OlAEiNpcc6mMyIYYWFICbrDFTrDR3wXqwc/Jkcx6L5VVWoagpSzbo3yGhc=
|
||||
|
||||
try {
|
||||
fileInputStream = new FileInputStream(signedFile);
|
||||
long skipped = fileInputStream.skip(Signature.SIGNATURE_BYTES);
|
||||
if (skipped != Signature.SIGNATURE_BYTES)
|
||||
return "";
|
||||
DataHelper.skip(fileInputStream, Signature.SIGNATURE_BYTES);
|
||||
byte[] data = new byte[VERSION_BYTES];
|
||||
int bytesRead = DataHelper.read(fileInputStream, data);
|
||||
|
||||
@@ -515,9 +513,7 @@ riCe6OlAEiNpcc6mMyIYYWFICbrDFTrDR3wXqwc/Jkcx6L5VVWoagpSzbo3yGhc=
|
||||
*/
|
||||
public static String getVersionString(InputStream inputStream) {
|
||||
try {
|
||||
long skipped = inputStream.skip(Signature.SIGNATURE_BYTES);
|
||||
if (skipped != Signature.SIGNATURE_BYTES)
|
||||
return "";
|
||||
DataHelper.skip(inputStream, Signature.SIGNATURE_BYTES);
|
||||
byte[] data = new byte[VERSION_BYTES];
|
||||
int bytesRead = DataHelper.read(inputStream, data);
|
||||
|
||||
@@ -640,10 +636,8 @@ riCe6OlAEiNpcc6mMyIYYWFICbrDFTrDR3wXqwc/Jkcx6L5VVWoagpSzbo3yGhc=
|
||||
try {
|
||||
fileInputStream = new FileInputStream(signedFile);
|
||||
fileOutputStream = new FileOutputStream(outputFile);
|
||||
long skipped = 0;
|
||||
|
||||
while (skipped < HEADER_BYTES)
|
||||
skipped += fileInputStream.skip(HEADER_BYTES - skipped);
|
||||
DataHelper.skip(fileInputStream, HEADER_BYTES);
|
||||
|
||||
byte[] buffer = new byte[16*1024];
|
||||
int bytesRead = 0;
|
||||
|
||||
@@ -1140,6 +1140,46 @@ public class DataHelper {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is different than InputStream.skip(), in that it
|
||||
* does repeated reads until the full amount is skipped.
|
||||
* To fix findbugs issues with skip().
|
||||
*
|
||||
* Guaranteed to skip exactly n bytes or throw an IOE.
|
||||
*
|
||||
* http://stackoverflow.com/questions/14057720/robust-skipping-of-data-in-a-java-io-inputstream-and-its-subtypes
|
||||
* http://stackoverflow.com/questions/11511093/java-inputstream-skip-return-value-near-end-of-file
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public static void skip(InputStream in, long n) throws IOException {
|
||||
if (n < 0)
|
||||
throw new IllegalArgumentException();
|
||||
if (n == 0)
|
||||
return;
|
||||
long read = 0;
|
||||
long nm1 = n - 1;
|
||||
if (nm1 > 0) {
|
||||
// skip all but the last byte
|
||||
do {
|
||||
long c = in.skip(nm1 - read);
|
||||
if (c < 0)
|
||||
throw new EOFException("EOF while skipping " + n + ", read only " + read);
|
||||
if (c == 0) {
|
||||
// see second SO link above
|
||||
if (in.read() == -1)
|
||||
throw new EOFException("EOF while skipping " + n + ", read only " + read);
|
||||
read++;
|
||||
} else {
|
||||
read += c;
|
||||
}
|
||||
} while (read < nm1);
|
||||
}
|
||||
// read the last byte to check for EOF
|
||||
if (in.read() == -1)
|
||||
throw new EOFException("EOF while skipping " + n + ", read only " + read);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is different than InputStream.read(target), in that it
|
||||
* does repeated reads until the full data is received.
|
||||
|
||||
@@ -209,14 +209,15 @@ public class Log {
|
||||
return;
|
||||
|
||||
// catenate all toString()s
|
||||
String descString = "close() loop in";
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("close() loop in");
|
||||
for (Object o : desc) {
|
||||
descString += " ";
|
||||
descString += String.valueOf(o);
|
||||
builder.append(" ");
|
||||
builder.append(String.valueOf(o));
|
||||
}
|
||||
|
||||
Exception e = new Exception("check stack trace");
|
||||
log(level,descString,e);
|
||||
log(level,builder.toString(),e);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
||||
@@ -149,7 +149,7 @@ public class SimpleTimer {
|
||||
}
|
||||
// FIXME if you plan to use this class again
|
||||
while (_events.containsKey(time))
|
||||
time = new Long(time.longValue() + 1);
|
||||
time = Long.valueOf(time.longValue() + 1);
|
||||
_events.put(time, event);
|
||||
_eventTimes.put(event, time);
|
||||
|
||||
|
||||
@@ -53,14 +53,14 @@ abstract class SipHashInline {
|
||||
// processing 8 bytes blocks in data
|
||||
while (i < last) {
|
||||
// pack a block to long, as LE 8 bytes
|
||||
m = (long) data[i++] |
|
||||
(long) data[i++] << 8 |
|
||||
(long) data[i++] << 16 |
|
||||
(long) data[i++] << 24 |
|
||||
(long) data[i++] << 32 |
|
||||
(long) data[i++] << 40 |
|
||||
(long) data[i++] << 48 |
|
||||
(long) data[i++] << 56 ;
|
||||
m = ((((long) data[i++]) & 0xff) ) |
|
||||
((((long) data[i++]) & 0xff) << 8) |
|
||||
((((long) data[i++]) & 0xff) << 16) |
|
||||
((((long) data[i++]) & 0xff) << 24) |
|
||||
((((long) data[i++]) & 0xff) << 32) |
|
||||
((((long) data[i++]) & 0xff) << 40) |
|
||||
((((long) data[i++]) & 0xff) << 48) |
|
||||
((((long) data[i++]) & 0xff) << 56);
|
||||
// MSGROUND {
|
||||
v3 ^= m;
|
||||
|
||||
@@ -132,7 +132,7 @@ abstract class SipHashInline {
|
||||
// packing the last block to long, as LE 0-7 bytes + the length in the top byte
|
||||
m = 0;
|
||||
for (i = off + len - 1; i >= last; --i) {
|
||||
m <<= 8; m |= (long) data[i];
|
||||
m <<= 8; m |= (long) (data[i] & 0xff);
|
||||
}
|
||||
m |= (long) len << 56;
|
||||
// MSGROUND {
|
||||
|
||||
@@ -69,12 +69,12 @@ public abstract class ZipFileComment {
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
if (skip > 0)
|
||||
in.skip(skip);
|
||||
DataHelper.skip(in, skip);
|
||||
byte[] hdr = new byte[HEADER_LEN];
|
||||
DataHelper.read(in, hdr);
|
||||
if (!DataHelper.eq(hdr, magicStart))
|
||||
throw new ZipException("Not a zip file: " + file);
|
||||
in.skip(fileLen - (skip + HEADER_LEN + buffer.length));
|
||||
DataHelper.skip(in, fileLen - (skip + HEADER_LEN + buffer.length));
|
||||
DataHelper.read(in, buffer);
|
||||
return getComment(buffer);
|
||||
} finally {
|
||||
|
||||
@@ -390,6 +390,7 @@ public class BSkipSpan extends SkipSpan {
|
||||
this.prev = null;
|
||||
|
||||
BSkipSpan bss = this;
|
||||
// findbugs ok (set in load() above)
|
||||
int np = nextPage;
|
||||
while(np != 0) {
|
||||
BSkipSpan temp = bsl.spanHash.get(Integer.valueOf(np));
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.i2p.data;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
@@ -126,4 +127,36 @@ public class DataHelperTest extends TestCase{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void testSkip() throws Exception {
|
||||
final int sz = 256;
|
||||
TestInputStream tis = new TestInputStream(sz);
|
||||
DataHelper.skip(tis, sz);
|
||||
try {
|
||||
DataHelper.skip(tis, 1);
|
||||
fail();
|
||||
} catch (IOException ioe) {}
|
||||
|
||||
DataHelper.skip(tis, 0);
|
||||
|
||||
try {
|
||||
DataHelper.skip(tis, -1);
|
||||
fail("skipped negative?");
|
||||
} catch (IllegalArgumentException expected) {}
|
||||
}
|
||||
|
||||
private static class TestInputStream extends ByteArrayInputStream {
|
||||
private final Random r = new Random();
|
||||
|
||||
public TestInputStream(int size) {
|
||||
super(new byte[size]);
|
||||
r.nextBytes(buf);
|
||||
}
|
||||
|
||||
/** skip a little at a time, or sometimes zero */
|
||||
@Override
|
||||
public long skip(long n) {
|
||||
return super.skip(Math.min(n, r.nextInt(4)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
installer/resources/themes/console/images/billiard_marker.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
installer/resources/themes/console/images/box_open.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
installer/resources/themes/console/images/group.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
installer/resources/themes/console/images/group_gear.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
installer/resources/themes/console/images/paste_plain.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
installer/resources/themes/console/images/television_delete.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
installer/resources/themes/console/images/user_astronaut.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
installer/resources/themes/console/images/world.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
@@ -525,10 +525,15 @@ public class Blocklist {
|
||||
byte[] pib = pa.getIP();
|
||||
if (pib == null) continue;
|
||||
// O(n**2)
|
||||
boolean dup = false;
|
||||
for (int i = 0; i < rv.size(); i++) {
|
||||
if (DataHelper.eq(rv.get(i), pib)) continue;
|
||||
if (DataHelper.eq(rv.get(i), pib)) {
|
||||
dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv.add(pib);
|
||||
if (!dup)
|
||||
rv.add(pib);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -374,8 +374,7 @@ public class MessageHistory {
|
||||
buf.append(getPrefix());
|
||||
buf.append("timed out waiting for a reply to [").append(sentMessage.getMessageType());
|
||||
buf.append("] [").append(sentMessage.getMessageId()).append("] expiring on [");
|
||||
if (sentMessage != null)
|
||||
buf.append(getTime(sentMessage.getReplySelector().getExpiration()));
|
||||
buf.append(getTime(sentMessage.getReplySelector().getExpiration()));
|
||||
buf.append("] ").append(sentMessage.getReplySelector().toString());
|
||||
addEntry(buf.toString());
|
||||
}
|
||||
|
||||
@@ -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 = 23;
|
||||
public final static long BUILD = 24;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
||||
@@ -86,7 +86,7 @@ public class StatisticsManager implements Service {
|
||||
|
||||
if (_context.getBooleanPropertyDefaultTrue(PROP_PUBLISH_RANKINGS) &&
|
||||
_context.random().nextInt(RANDOM_INCLUDE_STATS) == 0) {
|
||||
long publishedUptime = _context.router().getUptime();
|
||||
//long publishedUptime = _context.router().getUptime();
|
||||
// Don't publish these for first hour
|
||||
// Disabled in 0.9
|
||||
//if (publishedUptime > 62*60*1000)
|
||||
|
||||
@@ -223,7 +223,6 @@ public class HandleDatabaseLookupMessageJob extends JobImpl {
|
||||
private static boolean isUnreachable(RouterInfo info) {
|
||||
if (info == null) return true;
|
||||
String cap = info.getCapabilities();
|
||||
if (cap == null) return false;
|
||||
return cap.indexOf(Router.CAPABILITY_REACHABLE) >= 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ class FloodfillMonitorJob extends JobImpl {
|
||||
final RouterContext rc = getContext();
|
||||
final String log = String.format(
|
||||
"FF criteria breakdown: happy=%b, capabilities=%s, maxLag=%d, known=%d, " +
|
||||
"active=%d, participating=%d, offset=%d, ssuAddr=%b",
|
||||
"active=%d, participating=%d, offset=%d, ssuAddr=%s",
|
||||
happy,
|
||||
rc.router().getRouterInfo().getCapabilities(),
|
||||
rc.jobQueue().getMaxLag(),
|
||||
@@ -154,7 +154,7 @@ class FloodfillMonitorJob extends JobImpl {
|
||||
rc.commSystem().countActivePeers(),
|
||||
rc.tunnelManager().getParticipatingCount(),
|
||||
Math.abs(rc.clock().getOffset()),
|
||||
rc.router().getRouterInfo().getTargetAddress("SSU")
|
||||
rc.router().getRouterInfo().getTargetAddress("SSU").toString()
|
||||
);
|
||||
_log.debug(log);
|
||||
}
|
||||
|
||||
@@ -310,8 +310,6 @@ class FloodfillPeerSelector extends PeerSelector {
|
||||
if (pinfo == null)
|
||||
return rv;
|
||||
Collection<RouterAddress> paddr = pinfo.getAddresses();
|
||||
if (paddr == null)
|
||||
return rv;
|
||||
for (RouterAddress pa : paddr) {
|
||||
byte[] pib = pa.getIP();
|
||||
if (pib == null) continue;
|
||||
|
||||
@@ -926,7 +926,7 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
*/
|
||||
void dropAfterLookupFailed(Hash peer) {
|
||||
_context.peerManager().removeCapabilities(peer);
|
||||
boolean removed = _kb.remove(peer);
|
||||
_kb.remove(peer);
|
||||
//if (removed) {
|
||||
// if (_log.shouldLog(Log.INFO))
|
||||
// _log.info("Removed kbucket entry for " + peer);
|
||||
|
||||
@@ -1270,8 +1270,6 @@ public class ProfileOrganizer {
|
||||
if (pinfo == null)
|
||||
return rv;
|
||||
Collection<RouterAddress> paddr = pinfo.getAddresses();
|
||||
if (paddr == null)
|
||||
return rv;
|
||||
for (RouterAddress pa : paddr) {
|
||||
byte[] pib = pa.getIP();
|
||||
if (pib == null) continue;
|
||||
|
||||
@@ -83,7 +83,7 @@ class GeoIPv6 {
|
||||
if (!DataHelper.eq(magic, DataHelper.getASCII(MAGIC)))
|
||||
throw new IOException("Not a IPv6 geoip data file");
|
||||
// skip timestamp and comments
|
||||
in.skip(HEADER_LEN - MAGIC.length());
|
||||
DataHelper.skip(in, HEADER_LEN - MAGIC.length());
|
||||
byte[] buf = new byte[18];
|
||||
while (DataHelper.read(in, buf) == 18 && idx < search.length) {
|
||||
long ip1 = readLong(buf, 0);
|
||||
|
||||
@@ -139,12 +139,10 @@ public class OutboundMessageRegistry {
|
||||
|
||||
if (o instanceof OutNetMessage) {
|
||||
msg = (OutNetMessage)o;
|
||||
if (msg != null)
|
||||
rv.add(msg);
|
||||
rv.add(msg);
|
||||
} else if (o instanceof List) {
|
||||
msgs = (List<OutNetMessage>)o;
|
||||
if (msgs != null)
|
||||
rv.addAll(msgs);
|
||||
rv.addAll(msgs);
|
||||
}
|
||||
}
|
||||
if (removed) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -78,6 +79,8 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
|
||||
private Device _router;
|
||||
private Service _service;
|
||||
// UDN -> friendly name
|
||||
private final Map<String, String> _otherUDNs;
|
||||
private boolean isDisabled = false; // We disable the plugin if more than one IGD is found
|
||||
private volatile boolean _serviceLacksAPM;
|
||||
private final Object lock = new Object();
|
||||
@@ -92,6 +95,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
private ForwardPortCallback forwardCallback;
|
||||
|
||||
private static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
private static final String PROP_IGNORE = "i2np.upnp.ignore";
|
||||
|
||||
public UPnP(I2PAppContext context) {
|
||||
super();
|
||||
@@ -99,6 +103,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
_log = _context.logManager().getLog(UPnP.class);
|
||||
portsToForward = new HashSet<ForwardPort>();
|
||||
portsForwarded = new HashSet<ForwardPort>();
|
||||
_otherUDNs = new HashMap<String, String>(4);
|
||||
addDeviceChangeListener(this);
|
||||
}
|
||||
|
||||
@@ -178,21 +183,33 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
* DeviceChangeListener
|
||||
*/
|
||||
public void deviceAdded(Device dev) {
|
||||
String udn = dev.getUDN();
|
||||
if (udn == null)
|
||||
udn = "???";
|
||||
String name = dev.getFriendlyName();
|
||||
if (name == null)
|
||||
name = "???";
|
||||
synchronized (lock) {
|
||||
if(isDisabled) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Plugin has been disabled previously, ignoring new device.");
|
||||
_log.warn("Plugin has been disabled previously, ignoring " + name + " UDN: " + udn);
|
||||
_otherUDNs.put(udn, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!ROUTER_DEVICE.equals(dev.getDeviceType()) || !dev.isRootDevice()) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("UP&P non-IGD device found, ignoring : " + dev.getFriendlyName());
|
||||
_log.warn("UP&P non-IGD device found, ignoring " + name);
|
||||
synchronized (lock) {
|
||||
_otherUDNs.put(udn, name);
|
||||
}
|
||||
return; // ignore non-IGD devices
|
||||
} else if(isNATPresent()) {
|
||||
// maybe we should see if the old one went away before ignoring the new one?
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("UP&P ignoring additional IGD device found: " + dev.getFriendlyName() + " UDN: " + dev.getUDN());
|
||||
_log.logAlways(Log.WARN, "UP&P ignoring additional device " + name + " UDN: " + udn);
|
||||
synchronized (lock) {
|
||||
_otherUDNs.put(udn, name);
|
||||
}
|
||||
/********** seems a little drastic
|
||||
isDisabled = true;
|
||||
|
||||
@@ -206,11 +223,29 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("UP&P IGD found : " + dev.getFriendlyName() + " UDN: " + dev.getUDN() + " lease time: " + dev.getLeaseTime());
|
||||
synchronized(lock) {
|
||||
_router = dev;
|
||||
boolean ignore = false;
|
||||
String toIgnore = _context.getProperty(PROP_IGNORE);
|
||||
if (toIgnore != null) {
|
||||
String[] ignores = toIgnore.split("[,; \r\n\t]");
|
||||
for (int i = 0; i < ignores.length; i++) {
|
||||
if (ignores[i].equals(udn)) {
|
||||
ignore = true;
|
||||
_log.logAlways(Log.WARN, "Ignoring by config: " + name + " UDN: " + udn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized(lock) {
|
||||
if (ignore) {
|
||||
_otherUDNs.put(udn, name);
|
||||
return;
|
||||
} else {
|
||||
_router = dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("UP&P IGD found : " + name + " UDN: " + udn + " lease time: " + dev.getLeaseTime());
|
||||
|
||||
discoverService();
|
||||
// We have found the device we need: stop the listener thread
|
||||
@@ -303,16 +338,21 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
* DeviceChangeListener
|
||||
*/
|
||||
public void deviceRemoved(Device dev ){
|
||||
String udn = dev.getUDN();
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("UP&P device removed : " + dev.getFriendlyName() + " UDN: " + dev.getUDN());
|
||||
_log.warn("UP&P device removed : " + dev.getFriendlyName() + " UDN: " + udn);
|
||||
synchronized (lock) {
|
||||
if(_router == null) return;
|
||||
if (udn != null)
|
||||
_otherUDNs.remove(udn);
|
||||
else
|
||||
_otherUDNs.remove("???");
|
||||
// I2P this wasn't working
|
||||
//if(_router.equals(dev)) {
|
||||
if(ROUTER_DEVICE.equals(dev.getDeviceType()) &&
|
||||
dev.isRootDevice() &&
|
||||
stringEquals(_router.getFriendlyName(), dev.getFriendlyName()) &&
|
||||
stringEquals(_router.getUDN(), dev.getUDN())) {
|
||||
stringEquals(_router.getUDN(), udn)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("UP&P IGD device removed : " + dev.getFriendlyName());
|
||||
_router = null;
|
||||
@@ -375,7 +415,11 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
if(getIP == null || !getIP.postControlAction())
|
||||
return -1;
|
||||
|
||||
return Integer.valueOf(getIP.getOutputArgumentList().getArgument("NewUpstreamMaxBitRate").getValue());
|
||||
try {
|
||||
return Integer.parseInt(getIP.getOutputArgumentList().getArgument("NewUpstreamMaxBitRate").getValue());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,7 +433,11 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
if(getIP == null || !getIP.postControlAction())
|
||||
return -1;
|
||||
|
||||
return Integer.valueOf(getIP.getOutputArgumentList().getArgument("NewDownstreamMaxBitRate").getValue());
|
||||
try {
|
||||
return Integer.parseInt(getIP.getOutputArgumentList().getArgument("NewDownstreamMaxBitRate").getValue());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/** debug only */
|
||||
@@ -557,6 +605,21 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<h3><a name=\"upnp\"></a>").append(_("UPnP Status")).append("</h3>");
|
||||
|
||||
synchronized(_otherUDNs) {
|
||||
if (!_otherUDNs.isEmpty()) {
|
||||
sb.append(_("Disabled UPnP Devices"));
|
||||
sb.append("<ul>");
|
||||
for (Map.Entry<String, String> e : _otherUDNs.entrySet()) {
|
||||
String udn = e.getKey();
|
||||
String name = e.getValue();
|
||||
sb.append("<li>").append(name)
|
||||
.append("<br>UDN: ").append(udn)
|
||||
.append("</li>");
|
||||
}
|
||||
sb.append("</ul>");
|
||||
}
|
||||
}
|
||||
|
||||
if(isDisabled) {
|
||||
sb.append(_("UPnP has been disabled; Do you have more than one UPnP Internet Gateway Device on your LAN ?"));
|
||||
return sb.toString();
|
||||
|
||||
@@ -229,7 +229,7 @@ public class DHSessionKeyBuilder {
|
||||
//_peerValue = new NativeBigInteger(val);
|
||||
}
|
||||
|
||||
public BigInteger getPeerPublicValue() {
|
||||
public synchronized BigInteger getPeerPublicValue() {
|
||||
return _peerValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -952,8 +952,7 @@ public class NTCPTransport extends TransportImpl {
|
||||
}
|
||||
} else if (enabled.equals("false") &&
|
||||
name != null && name.length() > 0 &&
|
||||
!name.equals(ohost) &&
|
||||
nport != null) {
|
||||
!name.equals(ohost)) {
|
||||
// Host name is configured, and we have a port (either auto or configured)
|
||||
// but we probably only get here if the port is auto,
|
||||
// otherwise createNTCPAddress() would have done it already
|
||||
|
||||
@@ -1306,7 +1306,7 @@ class EstablishmentManager {
|
||||
_outboundByHash.remove(outboundState.getRemoteIdentity().calculateHash(), outboundState);
|
||||
// should have already been removed in handleOutbound() above
|
||||
// remove only if value == state
|
||||
boolean removed = _outboundStates.remove(outboundState.getRemoteHostId(), outboundState);
|
||||
_outboundStates.remove(outboundState.getRemoteHostId(), outboundState);
|
||||
if (outboundState.getState() != OB_STATE_CONFIRMED_COMPLETELY) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Expired: " + outboundState + " Lifetime: " + outboundState.getLifetime());
|
||||
|
||||
@@ -150,7 +150,6 @@ class OutboundMessageFragments {
|
||||
*
|
||||
*/
|
||||
public void add(OutNetMessage msg) {
|
||||
I2NPMessage msgBody = msg.getMessage();
|
||||
RouterInfo target = msg.getTarget();
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
@@ -363,14 +363,14 @@ class FragmentHandler {
|
||||
synchronized (_fragmentedMessages) {
|
||||
msg = _fragmentedMessages.get(Long.valueOf(messageId));
|
||||
if (msg == null) {
|
||||
msg = new FragmentedMessage(_context);
|
||||
msg = new FragmentedMessage(_context, messageId);
|
||||
_fragmentedMessages.put(Long.valueOf(messageId), msg);
|
||||
}
|
||||
}
|
||||
|
||||
// synchronized is required, fragments may be arriving in different threads
|
||||
synchronized(msg) {
|
||||
boolean ok = msg.receive(messageId, preprocessed, offset, size, false, router, tunnelId);
|
||||
boolean ok = msg.receive(preprocessed, offset, size, false, router, tunnelId);
|
||||
if (!ok) return -1;
|
||||
if (msg.isComplete()) {
|
||||
synchronized (_fragmentedMessages) {
|
||||
@@ -430,14 +430,14 @@ class FragmentHandler {
|
||||
synchronized (_fragmentedMessages) {
|
||||
msg = _fragmentedMessages.get(Long.valueOf(messageId));
|
||||
if (msg == null) {
|
||||
msg = new FragmentedMessage(_context);
|
||||
msg = new FragmentedMessage(_context, messageId);
|
||||
_fragmentedMessages.put(Long.valueOf(messageId), msg);
|
||||
}
|
||||
}
|
||||
|
||||
// synchronized is required, fragments may be arriving in different threads
|
||||
synchronized(msg) {
|
||||
boolean ok = msg.receive(messageId, fragmentNum, preprocessed, offset, size, isLast);
|
||||
boolean ok = msg.receive(fragmentNum, preprocessed, offset, size, isLast);
|
||||
if (!ok) return -1;
|
||||
|
||||
if (msg.isComplete()) {
|
||||
|
||||
@@ -19,7 +19,7 @@ import net.i2p.util.SimpleTimer2;
|
||||
class FragmentedMessage {
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private long _messageId;
|
||||
private final long _messageId;
|
||||
private Hash _toRouter;
|
||||
private TunnelId _toTunnel;
|
||||
private final ByteArray _fragments[];
|
||||
@@ -33,11 +33,12 @@ class FragmentedMessage {
|
||||
private static final ByteCache _cache = ByteCache.getInstance(512, TrivialPreprocessor.PREPROCESSED_SIZE);
|
||||
// 64 is pretty absurd, 32 is too, most likely
|
||||
private static final int MAX_FRAGMENTS = 64;
|
||||
private static final int MAX_FRAGMENT_SIZE = 996;
|
||||
|
||||
public FragmentedMessage(I2PAppContext ctx) {
|
||||
public FragmentedMessage(I2PAppContext ctx, long messageId) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(FragmentedMessage.class);
|
||||
_messageId = -1;
|
||||
_messageId = messageId;
|
||||
_fragments = new ByteArray[MAX_FRAGMENTS];
|
||||
_highFragmentNum = -1;
|
||||
_releasedAfter = -1;
|
||||
@@ -48,37 +49,30 @@ class FragmentedMessage {
|
||||
* Receive a followup fragment, though one of these may arrive at the endpoint
|
||||
* prior to the fragment # 0.
|
||||
*
|
||||
* @param messageId what messageId is this fragment a part of
|
||||
* @param fragmentNum sequence number within the message (must be greater than 1)
|
||||
* @param payload data for the fragment
|
||||
* @param fragmentNum sequence number within the message (1 - 63)
|
||||
* @param payload data for the fragment non-null
|
||||
* @param offset index into the payload where the fragment data starts (past headers/etc)
|
||||
* @param length how much past the offset should we snag?
|
||||
* @param isLast is this the last fragment in the message?
|
||||
*/
|
||||
public boolean receive(long messageId, int fragmentNum, byte payload[], int offset, int length, boolean isLast) {
|
||||
if (fragmentNum < 0) {
|
||||
public boolean receive(int fragmentNum, byte payload[], int offset, int length, boolean isLast) {
|
||||
if (fragmentNum <= 0 || fragmentNum >= MAX_FRAGMENTS) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Fragment # == " + fragmentNum + " for messageId " + messageId);
|
||||
_log.error("Fragment # == " + fragmentNum + " for messageId " + _messageId);
|
||||
return false;
|
||||
}
|
||||
if (payload == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Payload is null for messageId " + messageId);
|
||||
return false;
|
||||
}
|
||||
if (length <= 0) {
|
||||
if (length <= 0 || length > MAX_FRAGMENT_SIZE) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Length is impossible (" + length + ") for messageId " + messageId);
|
||||
_log.warn("Length is impossible (" + length + ") for messageId " + _messageId);
|
||||
return false;
|
||||
}
|
||||
if (offset + length > payload.length) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Length is impossible (" + length + "/" + offset + " out of " + payload.length + ") for messageId " + messageId);
|
||||
_log.warn("Length is impossible (" + length + "/" + offset + " out of " + payload.length + ") for messageId " + _messageId);
|
||||
return false;
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Receive message " + messageId + " fragment " + fragmentNum + " with " + length + " bytes (last? " + isLast + ") offset = " + offset);
|
||||
_messageId = messageId;
|
||||
_log.debug("Receive message " + _messageId + " fragment " + fragmentNum + " with " + length + " bytes (last? " + isLast + ") offset = " + offset);
|
||||
// we should just use payload[] and use an offset/length on it
|
||||
ByteArray ba = _cache.acquire(); //new ByteArray(payload, offset, length); //new byte[length]);
|
||||
System.arraycopy(payload, offset, ba.getData(), 0, length);
|
||||
@@ -95,43 +89,36 @@ class FragmentedMessage {
|
||||
_highFragmentNum = fragmentNum;
|
||||
if (isLast && fragmentNum <= 0) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("hmm, isLast and fragmentNum=" + fragmentNum + " for message " + messageId);
|
||||
_log.error("hmm, isLast and fragmentNum=" + fragmentNum + " for message " + _messageId);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive the first fragment and related metadata. This may not be the first
|
||||
* Receive the first fragment (#0) and related metadata. This may not be the first
|
||||
* one to arrive at the endpoint however.
|
||||
*
|
||||
* @param messageId what messageId is this fragment a part of
|
||||
* @param payload data for the fragment
|
||||
* @param payload data for the fragment non-null
|
||||
* @param offset index into the payload where the fragment data starts (past headers/etc)
|
||||
* @param length how much past the offset should we snag?
|
||||
* @param isLast is this the last fragment in the message?
|
||||
* @param toRouter what router is this destined for (may be null)
|
||||
* @param toTunnel what tunnel is this destined for (may be null)
|
||||
*/
|
||||
public boolean receive(long messageId, byte payload[], int offset, int length, boolean isLast, Hash toRouter, TunnelId toTunnel) {
|
||||
if (payload == null) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Payload is null for messageId " + messageId);
|
||||
return false;
|
||||
}
|
||||
if (length <= 0) {
|
||||
public boolean receive(byte payload[], int offset, int length, boolean isLast, Hash toRouter, TunnelId toTunnel) {
|
||||
if (length <= 0 || length > MAX_FRAGMENT_SIZE) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Length is impossible (" + length + ") for messageId " + messageId);
|
||||
_log.warn("Length is impossible (" + length + ") for messageId " + _messageId);
|
||||
return false;
|
||||
}
|
||||
if (offset + length > payload.length) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Length is impossible (" + length + "/" + offset + " out of " + payload.length + ") for messageId " + messageId);
|
||||
_log.warn("Length is impossible (" + length + "/" + offset + " out of " + payload.length + ") for messageId " + _messageId);
|
||||
return false;
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Receive message " + messageId + " with " + length + " bytes (last? " + isLast + ") targetting " + toRouter + " / " + toTunnel + " offset=" + offset);
|
||||
_messageId = messageId;
|
||||
_log.debug("Receive message " + _messageId + " with " + length + " bytes (last? " + isLast + ") targetting " + toRouter + " / " + toTunnel + " offset=" + offset);
|
||||
ByteArray ba = _cache.acquire(); // new ByteArray(payload, offset, length); // new byte[length]);
|
||||
System.arraycopy(payload, offset, ba.getData(), 0, length);
|
||||
ba.setValid(length);
|
||||
|
||||
@@ -58,7 +58,7 @@ class OutboundTunnelEndpoint {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("outbound tunnel " + _config + " received a full message: " + msg
|
||||
+ " to be forwarded on to "
|
||||
+ (toRouter != null ? toRouter.toBase64().substring(0,4) : "")
|
||||
+ toRouter.toBase64().substring(0,4)
|
||||
+ (toTunnel != null ? ":" + toTunnel.getTunnelId() : ""));
|
||||
int size = msg.getMessageSize();
|
||||
// don't drop it if we are the target
|
||||
|
||||
@@ -348,9 +348,6 @@ public abstract class TunnelPeerSelector {
|
||||
|
||||
private static boolean shouldExclude(RouterContext ctx, Log log, RouterInfo peer, char excl[]) {
|
||||
String cap = peer.getCapabilities();
|
||||
if (cap == null) {
|
||||
return true;
|
||||
}
|
||||
for (int j = 0; j < excl.length; j++) {
|
||||
if (cap.indexOf(excl[j]) >= 0) {
|
||||
return true;
|
||||
|
||||
@@ -79,8 +79,8 @@ public class DecayingHashSet extends DecayingBloomFilter {
|
||||
throw new IllegalArgumentException("Bad size");
|
||||
_current = new ConcurrentHashSet(128);
|
||||
_previous = new ConcurrentHashSet(128);
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("New DHS " + name + " entryBytes = " + entryBytes +
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("New DHS " + name + " entryBytes = " + entryBytes +
|
||||
" cycle (s) = " + (durationMs / 1000));
|
||||
// try to get a handle on memory usage vs. false positives
|
||||
context.statManager().createRateStat("router.decayingHashSet." + name + ".size",
|
||||
|
||||
@@ -45,16 +45,16 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
*/
|
||||
|
||||
public class BloomSHA1 {
|
||||
protected final int m;
|
||||
protected final int k;
|
||||
protected int count;
|
||||
private final int m;
|
||||
private final int k;
|
||||
private int count;
|
||||
|
||||
protected final int[] filter;
|
||||
protected final KeySelector ks;
|
||||
private final int[] filter;
|
||||
private final KeySelector ks;
|
||||
|
||||
// convenience variables
|
||||
protected final int filterBits;
|
||||
protected final int filterWords;
|
||||
private final int filterBits;
|
||||
private final int filterWords;
|
||||
|
||||
private final BlockingQueue<int[]> buf;
|
||||
|
||||
@@ -120,7 +120,7 @@ public class BloomSHA1 {
|
||||
this (20, 8);
|
||||
}
|
||||
/** Clear the filter, unsynchronized */
|
||||
protected void doClear() {
|
||||
private void doClear() {
|
||||
Arrays.fill(filter, 0);
|
||||
count = 0;
|
||||
}
|
||||
@@ -186,9 +186,9 @@ public class BloomSHA1 {
|
||||
* @param b byte array representing a key (SHA1 digest)
|
||||
* @return true if b is in the filter
|
||||
*/
|
||||
protected final boolean isMember(byte[] b) { return isMember(b, 0, b.length); }
|
||||
private final boolean isMember(byte[] b) { return isMember(b, 0, b.length); }
|
||||
|
||||
protected final boolean isMember(byte[] b, int offset, int len) {
|
||||
private final boolean isMember(byte[] b, int offset, int len) {
|
||||
int[] bitOffset = acquire();
|
||||
int[] wordOffset = acquire();
|
||||
ks.getOffsets(b, offset, len, bitOffset, wordOffset);
|
||||
|
||||
@@ -40,14 +40,14 @@ public class KeySelector {
|
||||
}
|
||||
|
||||
/** AND with byte to expose index-many bits */
|
||||
public final static int[] UNMASK = {
|
||||
private final static int[] UNMASK = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767};
|
||||
/** AND with byte to zero out index-many bits */
|
||||
public final static int[] MASK = {
|
||||
private final static int[] MASK = {
|
||||
~0,~1,~3,~7,~15,~31,~63,~127,~255,~511,~1023,~2047,~4095,~8191,~16383,~32767};
|
||||
|
||||
public final static int TWO_UP_15 = 32 * 1024;
|
||||
private final static int TWO_UP_15 = 32 * 1024;
|
||||
|
||||
/**
|
||||
* Creates a key selector for a Bloom filter. When a key is presented
|
||||
|
||||