forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p' (head 4a63eba1606a8ba2448352876b4177d9e4c753a1)
to branch 'i2p.i2p.unittests' (head 051ea486db9f6f5a4327038827763f350369f932)
This commit is contained in:
31
core/java/src/gnu/getopt/MessagesBundle_fi.properties
Normal file
31
core/java/src/gnu/getopt/MessagesBundle_fi.properties
Normal file
@ -0,0 +1,31 @@
|
||||
#**************************************************************************
|
||||
#* MessagesBundle.properties -- English language error messages
|
||||
#*
|
||||
#* Copyright (c) 1998 by William King (wrking@eng.sun.com) and
|
||||
#* Aaron M. Renn (arenn@urbanophile.com)
|
||||
#*
|
||||
#* This program is free software; you can redistribute it and/or modify
|
||||
#* it under the terms of the GNU Library General Public License as published
|
||||
#* by the Free Software Foundation; either version 2 of the License or
|
||||
#* (at your option) any later version.
|
||||
#*
|
||||
#* This program is distributed in the hope that it will be useful, but
|
||||
#* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#* GNU Library General Public License for more details.
|
||||
#*
|
||||
#* You should have received a copy of the GNU Library General Public License
|
||||
#* along with this program; see the file COPYING.LIB. If not, write to
|
||||
#* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
|
||||
#* Boston, MA 02111-1307 USA
|
||||
#**************************************************************************/
|
||||
getopt.ambigious={0}\: valitsin \u201d{1}\u201d ei ole yksiselitteinen
|
||||
getopt.arguments1={0}\: valitsin ''--{1}'' ei salli argumenttia
|
||||
getopt.arguments2={0}\: valitsin ''{1}{2}'' ei salli argumenttia
|
||||
getopt.requires={0}\: valitsin ''{1}'' vaatii argumentin
|
||||
getopt.unrecognized={0}\: tunnistamaton valitsin ''--{1}''
|
||||
getopt.unrecognized2={0}\: tunnistamaton valitsin ''{1}{2}''
|
||||
getopt.illegal={0}\: virheellinen valitsin -- {1}
|
||||
getopt.invalid={0}\: virheellinen valitsin -- {1}
|
||||
getopt.requires2={0}\: valitsin vaatii argumentin -- {1}
|
||||
getopt.invalidValue=Virheellinen arvo {0} parametrille 'has_arg'
|
@ -18,7 +18,7 @@ public class CoreVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
|
||||
public final static String VERSION = "0.9.20";
|
||||
public final static String VERSION = "0.9.22";
|
||||
|
||||
/**
|
||||
* For Vuze.
|
||||
|
@ -96,7 +96,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
|
||||
// established subsessions
|
||||
private final ConcurrentHashMap<SessionId, SubSession> _subsessionMap;
|
||||
private final Object _subsessionLock = new Object();
|
||||
private static final String MIN_SUBSESSION_VERSION = "0.9.19";
|
||||
private static final String MIN_SUBSESSION_VERSION = "0.9.21";
|
||||
private volatile boolean _routerSupportsSubsessions;
|
||||
|
||||
/** hostname of router - will be null if in RouterContext */
|
||||
|
@ -501,6 +501,7 @@ public class KeyStoreUtil {
|
||||
l.log(level, msg, t);
|
||||
}
|
||||
|
||||
/****
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
if (args.length > 0) {
|
||||
@ -521,4 +522,5 @@ public class KeyStoreUtil {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
****/
|
||||
}
|
||||
|
@ -540,9 +540,10 @@ public class SU3File {
|
||||
String ctype = null;
|
||||
String ftype = null;
|
||||
String kfile = null;
|
||||
String kspass = KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD;
|
||||
boolean error = false;
|
||||
boolean shouldVerify = true;
|
||||
Getopt g = new Getopt("SU3File", args, "t:c:f:k:x");
|
||||
Getopt g = new Getopt("SU3File", args, "t:c:f:k:xp:");
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
switch (c) {
|
||||
@ -566,6 +567,10 @@ public class SU3File {
|
||||
shouldVerify = false;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
kspass = g.getOptarg();
|
||||
break;
|
||||
|
||||
case '?':
|
||||
case ':':
|
||||
default:
|
||||
@ -586,16 +591,16 @@ public class SU3File {
|
||||
Properties props = new Properties();
|
||||
props.setProperty("prng.bufferSize", "16384");
|
||||
new I2PAppContext(props);
|
||||
ok = signCLI(stype, ctype, ftype, a.get(0), a.get(1), a.get(2), a.get(3), a.get(4), "");
|
||||
ok = signCLI(stype, ctype, ftype, a.get(0), a.get(1), a.get(2), a.get(3), a.get(4), "", kspass);
|
||||
} else if ("bulksign".equals(cmd)) {
|
||||
Properties props = new Properties();
|
||||
props.setProperty("prng.bufferSize", "16384");
|
||||
new I2PAppContext(props);
|
||||
ok = bulkSignCLI(stype, ctype, a.get(0), a.get(1), a.get(2), a.get(3));
|
||||
ok = bulkSignCLI(stype, ctype, a.get(0), a.get(1), a.get(2), a.get(3), kspass);
|
||||
} else if ("verifysig".equals(cmd)) {
|
||||
ok = verifySigCLI(a.get(0), kfile);
|
||||
} else if ("keygen".equals(cmd)) {
|
||||
ok = genKeysCLI(stype, a.get(0), a.get(1), a.get(2));
|
||||
ok = genKeysCLI(stype, a.get(0), a.get(1), a.get(2), kspass);
|
||||
} else if ("extract".equals(cmd)) {
|
||||
ok = extractCLI(a.get(0), a.get(1), shouldVerify, kfile);
|
||||
} else {
|
||||
@ -611,12 +616,13 @@ public class SU3File {
|
||||
}
|
||||
|
||||
private static final void showUsageCLI() {
|
||||
System.err.println("Usage: SU3File keygen [-t type|code] publicKeyFile keystore.ks you@mail.i2p");
|
||||
System.err.println(" SU3File sign [-t type|code] [-c type|code] [-f type|code] inputFile.zip signedFile.su3 keystore.ks version you@mail.i2p");
|
||||
System.err.println(" SU3File bulksign [-t type|code] [-c type|code] directory keystore.ks version you@mail.i2p");
|
||||
System.err.println(" SU3File showversion signedFile.su3");
|
||||
System.err.println(" SU3File verifysig [-k file.crt] signedFile.su3 ## -k use this pubkey cert for verification");
|
||||
System.err.println(" SU3File extract [-x] [-k file.crt] signedFile.su3 outFile ## -x don't check sig");
|
||||
System.err.println("Usage: SU3File keygen [-t type|code] [-p keystorepw] publicKeyFile keystore.ks you@mail.i2p\n" +
|
||||
" SU3File sign [-t type|code] [-c type|code] [-f type|code] [-p keystorepw] inputFile.zip signedFile.su3 keystore.ks version you@mail.i2p\n" +
|
||||
" SU3File bulksign [-t type|code] [-c type|code] [-p keystorepw] directory keystore.ks version you@mail.i2p\n" +
|
||||
" SU3File showversion signedFile.su3\n" +
|
||||
" SU3File verifysig [-k file.crt] signedFile.su3 ## -k use this pubkey cert for verification\n" +
|
||||
" SU3File extract [-x] [-k file.crt] signedFile.su3 outFile ## -x don't check sig");
|
||||
System.err.println("Default keystore password: \"" + KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD + '"');
|
||||
System.err.println(dumpTypes());
|
||||
}
|
||||
|
||||
@ -714,7 +720,7 @@ public class SU3File {
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean bulkSignCLI(String stype, String ctype, String dir,
|
||||
String privateKeyFile, String version, String signerName) {
|
||||
String privateKeyFile, String version, String signerName, String kspass) {
|
||||
File d = new File(dir);
|
||||
if (!d.isDirectory()) {
|
||||
System.out.println("Directory does not exist: " + d);
|
||||
@ -749,7 +755,8 @@ public class SU3File {
|
||||
if (!inputFile.endsWith(".zip"))
|
||||
continue;
|
||||
String signedFile = inputFile.substring(0, inputFile.length() - 4) + ".su3";
|
||||
boolean rv = signCLI(stype, ctype, null, inputFile, signedFile, privateKeyFile, version, signerName, keypw);
|
||||
boolean rv = signCLI(stype, ctype, null, inputFile, signedFile,
|
||||
privateKeyFile, version, signerName, keypw, kspass);
|
||||
if (!rv)
|
||||
return false;
|
||||
success++;
|
||||
@ -764,7 +771,7 @@ public class SU3File {
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean signCLI(String stype, String ctype, String ftype, String inputFile, String signedFile,
|
||||
String privateKeyFile, String version, String signerName, String keypw) {
|
||||
String privateKeyFile, String version, String signerName, String keypw, String kspass) {
|
||||
SigType type = stype == null ? SigType.getByCode(Integer.valueOf(DEFAULT_SIG_CODE)) : SigType.parseSigType(stype);
|
||||
if (type == null) {
|
||||
System.out.println("Signature type " + stype + " is not supported");
|
||||
@ -799,7 +806,7 @@ public class SU3File {
|
||||
System.out.println("Warning: File type " + ftype + " is undefined");
|
||||
}
|
||||
}
|
||||
return signCLI(type, ct, ft, inputFile, signedFile, privateKeyFile, version, signerName, keypw);
|
||||
return signCLI(type, ct, ft, inputFile, signedFile, privateKeyFile, version, signerName, keypw, kspass);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -807,7 +814,7 @@ public class SU3File {
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean signCLI(SigType type, ContentType ctype, int ftype, String inputFile, String signedFile,
|
||||
String privateKeyFile, String version, String signerName, String keypw) {
|
||||
String privateKeyFile, String version, String signerName, String keypw, String kspass) {
|
||||
try {
|
||||
while (keypw.length() < 6) {
|
||||
System.out.print("Enter password for key \"" + signerName + "\": ");
|
||||
@ -821,7 +828,7 @@ public class SU3File {
|
||||
System.out.println("Key password must be at least 6 characters");
|
||||
}
|
||||
File pkfile = new File(privateKeyFile);
|
||||
PrivateKey pk = KeyStoreUtil.getPrivateKey(pkfile,KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, signerName, keypw);
|
||||
PrivateKey pk = KeyStoreUtil.getPrivateKey(pkfile, kspass, signerName, keypw);
|
||||
if (pk == null) {
|
||||
System.out.println("Private key for " + signerName + " not found in keystore " + privateKeyFile);
|
||||
return false;
|
||||
@ -895,13 +902,14 @@ public class SU3File {
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean genKeysCLI(String stype, String publicKeyFile, String privateKeyFile, String alias) {
|
||||
private static final boolean genKeysCLI(String stype, String publicKeyFile, String privateKeyFile,
|
||||
String alias, String kspass) {
|
||||
SigType type = stype == null ? SigType.getByCode(Integer.valueOf(DEFAULT_SIG_CODE)) : SigType.parseSigType(stype);
|
||||
if (type == null) {
|
||||
System.out.println("Signature type " + stype + " is not supported");
|
||||
return false;
|
||||
}
|
||||
return genKeysCLI(type, publicKeyFile, privateKeyFile, alias);
|
||||
return genKeysCLI(type, publicKeyFile, privateKeyFile, alias, kspass);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -909,7 +917,8 @@ public class SU3File {
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean genKeysCLI(SigType type, String publicKeyFile, String privateKeyFile, String alias) {
|
||||
private static final boolean genKeysCLI(SigType type, String publicKeyFile, String privateKeyFile,
|
||||
String alias, String kspass) {
|
||||
File pubFile = new File(publicKeyFile);
|
||||
if (pubFile.exists()) {
|
||||
System.out.println("Error: Not overwriting file " + publicKeyFile);
|
||||
@ -947,7 +956,7 @@ public class SU3File {
|
||||
if (keylen == 528)
|
||||
keylen = 521;
|
||||
}
|
||||
boolean success = KeyStoreUtil.createKeys(ksFile, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, alias,
|
||||
boolean success = KeyStoreUtil.createKeys(ksFile, kspass, alias,
|
||||
alias, "I2P", 3652, type.getBaseAlgorithm().getName(),
|
||||
keylen, keypw);
|
||||
if (!success) {
|
||||
|
@ -47,16 +47,17 @@ public class Certificate extends DataStructureImpl {
|
||||
public final static int CERTIFICATE_TYPE_KEY = 5;
|
||||
|
||||
/**
|
||||
* If null cert, return immutable static instance, else create new
|
||||
* If null, P256 key, or Ed25519 key cert, return immutable static instance, else create new
|
||||
* @throws DataFormatException if not enough bytes
|
||||
* @since 0.8.3
|
||||
*/
|
||||
public static Certificate create(byte[] data, int off) throws DataFormatException {
|
||||
int type;
|
||||
byte[] payload;
|
||||
int length;
|
||||
try {
|
||||
type = data[off] & 0xff;
|
||||
int length = (int) DataHelper.fromLong(data, off + 1, 2);
|
||||
length = (int) DataHelper.fromLong(data, off + 1, 2);
|
||||
if (type == 0 && length == 0)
|
||||
return NULL_CERT;
|
||||
// from here down roughly the same as readBytes() below
|
||||
@ -68,6 +69,12 @@ public class Certificate extends DataStructureImpl {
|
||||
throw new DataFormatException("not enough bytes", aioobe);
|
||||
}
|
||||
if (type == CERTIFICATE_TYPE_KEY) {
|
||||
if (length == 4) {
|
||||
if (Arrays.equals(payload, KeyCertificate.Ed25519_PAYLOAD))
|
||||
return KeyCertificate.ELG_Ed25519_CERT;
|
||||
if (Arrays.equals(payload, KeyCertificate.ECDSA256_PAYLOAD))
|
||||
return KeyCertificate.ELG_ECDSA256_CERT;
|
||||
}
|
||||
try {
|
||||
return new KeyCertificate(payload);
|
||||
} catch (DataFormatException dfe) {
|
||||
@ -78,7 +85,7 @@ public class Certificate extends DataStructureImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* If null cert, return immutable static instance, else create new
|
||||
* If null, P256 key, or Ed25519 key cert, return immutable static instance, else create new
|
||||
* @since 0.8.3
|
||||
*/
|
||||
public static Certificate create(InputStream in) throws DataFormatException, IOException {
|
||||
@ -93,8 +100,15 @@ public class Certificate extends DataStructureImpl {
|
||||
int read = DataHelper.read(in, payload);
|
||||
if (read != length)
|
||||
throw new DataFormatException("Not enough bytes for the payload (read: " + read + " length: " + length + ')');
|
||||
if (type == CERTIFICATE_TYPE_KEY)
|
||||
if (type == CERTIFICATE_TYPE_KEY) {
|
||||
if (length == 4) {
|
||||
if (Arrays.equals(payload, KeyCertificate.Ed25519_PAYLOAD))
|
||||
return KeyCertificate.ELG_Ed25519_CERT;
|
||||
if (Arrays.equals(payload, KeyCertificate.ECDSA256_PAYLOAD))
|
||||
return KeyCertificate.ELG_ECDSA256_CERT;
|
||||
}
|
||||
return new KeyCertificate(payload);
|
||||
}
|
||||
return new Certificate(type, payload);
|
||||
}
|
||||
|
||||
|
@ -1546,7 +1546,7 @@ public class DataHelper {
|
||||
// years
|
||||
t = ngettext("1 year", "{0} years", (int) (ms / (365L * 24 * 60 * 60 * 1000)));
|
||||
} else {
|
||||
return _("n/a");
|
||||
return _t("n/a");
|
||||
}
|
||||
// Replace minus sign to work around
|
||||
// bug in Chrome (and IE?), line breaks at the minus sign
|
||||
@ -1593,7 +1593,7 @@ public class DataHelper {
|
||||
// years
|
||||
t = ngettext("1 year", "{0} years", (int) (ms / (365L * 24 * 60 * 60 * 1000)));
|
||||
} else {
|
||||
return _("n/a");
|
||||
return _t("n/a");
|
||||
}
|
||||
if (ms < 0)
|
||||
t = t.replace("-", "−");
|
||||
@ -1602,7 +1602,7 @@ public class DataHelper {
|
||||
|
||||
private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
|
||||
|
||||
private static String _(String key) {
|
||||
private static String _t(String key) {
|
||||
return Translate.getString(key, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
|
@ -17,15 +17,41 @@ public class KeyCertificate extends Certificate {
|
||||
|
||||
public static final int HEADER_LENGTH = 4;
|
||||
|
||||
/** @since 0.9.22 pkg private for Certificate.create() */
|
||||
static final byte[] Ed25519_PAYLOAD = new byte[] {
|
||||
0, (byte) (SigType.EdDSA_SHA512_Ed25519.getCode()), 0, 0
|
||||
};
|
||||
|
||||
/** @since 0.9.22 pkg private for Certificate.create() */
|
||||
static final byte[] ECDSA256_PAYLOAD = new byte[] {
|
||||
0, (byte) (SigType.ECDSA_SHA256_P256.getCode()), 0, 0
|
||||
};
|
||||
|
||||
/**
|
||||
* An immutable ElG/ECDSA-P256 certificate.
|
||||
*/
|
||||
public static final KeyCertificate ELG_ECDSA256_CERT;
|
||||
|
||||
/**
|
||||
* An immutable ElG/Ed25519 certificate.
|
||||
* @since 0.9.22
|
||||
*/
|
||||
public static final KeyCertificate ELG_Ed25519_CERT;
|
||||
|
||||
static {
|
||||
KeyCertificate kc;
|
||||
try {
|
||||
kc = new ECDSA256Cert();
|
||||
} catch (DataFormatException dfe) {
|
||||
kc = null; // won't happen
|
||||
throw new RuntimeException(dfe); // won't happen
|
||||
}
|
||||
ELG_ECDSA256_CERT = kc;
|
||||
try {
|
||||
kc = new Ed25519Cert();
|
||||
} catch (DataFormatException dfe) {
|
||||
throw new RuntimeException(dfe); // won't happen
|
||||
}
|
||||
ELG_Ed25519_CERT = kc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,19 +211,17 @@ public class KeyCertificate extends Certificate {
|
||||
|
||||
/**
|
||||
* An immutable ElG/ECDSA-256 certificate.
|
||||
* @since 0.8.3
|
||||
*/
|
||||
private static final class ECDSA256Cert extends KeyCertificate {
|
||||
private static final byte[] ECDSA256_DATA = new byte[] {
|
||||
CERTIFICATE_TYPE_KEY, 0, HEADER_LENGTH, 0, (byte) (SigType.ECDSA_SHA256_P256.getCode()), 0, 0
|
||||
};
|
||||
private static final int ECDSA256_LENGTH = ECDSA256_DATA.length;
|
||||
private static final byte[] ECDSA256_PAYLOAD = new byte[] {
|
||||
0, (byte) (SigType.ECDSA_SHA256_P256.getCode()), 0, 0
|
||||
};
|
||||
private final int _hashcode;
|
||||
|
||||
public ECDSA256Cert() throws DataFormatException {
|
||||
super(ECDSA256_PAYLOAD);
|
||||
_hashcode = super.hashCode();
|
||||
}
|
||||
|
||||
/** @throws RuntimeException always */
|
||||
@ -246,7 +270,75 @@ public class KeyCertificate extends Certificate {
|
||||
/** Overridden for efficiency */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 1234567;
|
||||
return _hashcode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An immutable ElG/Ed25519 certificate.
|
||||
* @since 0.9.22
|
||||
*/
|
||||
private static final class Ed25519Cert extends KeyCertificate {
|
||||
private static final byte[] ED_DATA = new byte[] { CERTIFICATE_TYPE_KEY,
|
||||
0, HEADER_LENGTH,
|
||||
0, (byte) SigType.EdDSA_SHA512_Ed25519.getCode(),
|
||||
0, 0
|
||||
};
|
||||
private static final int ED_LENGTH = ED_DATA.length;
|
||||
private final int _hashcode;
|
||||
|
||||
public Ed25519Cert() throws DataFormatException {
|
||||
super(Ed25519_PAYLOAD);
|
||||
_hashcode = super.hashCode();
|
||||
}
|
||||
|
||||
/** @throws RuntimeException always */
|
||||
@Override
|
||||
public void setCertificateType(int type) {
|
||||
throw new RuntimeException("Data already set");
|
||||
}
|
||||
|
||||
/** @throws RuntimeException always */
|
||||
@Override
|
||||
public void setPayload(byte[] payload) {
|
||||
throw new RuntimeException("Data already set");
|
||||
}
|
||||
|
||||
/** @throws RuntimeException always */
|
||||
@Override
|
||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
||||
throw new RuntimeException("Data already set");
|
||||
}
|
||||
|
||||
/** Overridden for efficiency */
|
||||
@Override
|
||||
public void writeBytes(OutputStream out) throws IOException {
|
||||
out.write(ED_DATA);
|
||||
}
|
||||
|
||||
/** Overridden for efficiency */
|
||||
@Override
|
||||
public int writeBytes(byte target[], int offset) {
|
||||
System.arraycopy(ED_DATA, 0, target, offset, ED_LENGTH);
|
||||
return ED_LENGTH;
|
||||
}
|
||||
|
||||
/** @throws RuntimeException always */
|
||||
@Override
|
||||
public int readBytes(byte source[], int offset) throws DataFormatException {
|
||||
throw new RuntimeException("Data already set");
|
||||
}
|
||||
|
||||
/** Overridden for efficiency */
|
||||
@Override
|
||||
public int size() {
|
||||
return ED_LENGTH;
|
||||
}
|
||||
|
||||
/** Overridden for efficiency */
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return _hashcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.i2p.internal;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
import net.i2p.data.i2cp.I2CPMessage;
|
||||
|
||||
/**
|
||||
@ -15,7 +17,7 @@ import net.i2p.data.i2cp.I2CPMessage;
|
||||
* @author zzz
|
||||
* @since 0.8.3
|
||||
*/
|
||||
public abstract class I2CPMessageQueue {
|
||||
public abstract class I2CPMessageQueue implements Closeable {
|
||||
|
||||
/**
|
||||
* Send a message, nonblocking.
|
||||
|
@ -178,6 +178,7 @@ public interface UpdateManager {
|
||||
* @since 0.9.21
|
||||
*/
|
||||
public boolean isUpdateInProgress(UpdateType type, String id);
|
||||
|
||||
/**
|
||||
* Non-blocking. Does not check.
|
||||
* Fails if check or update already in progress.
|
||||
@ -225,6 +226,7 @@ public interface UpdateManager {
|
||||
/**
|
||||
* The status on any update current or last finished.
|
||||
* @return status or ""
|
||||
* @since 0.9.21
|
||||
*/
|
||||
public String getStatus();
|
||||
|
||||
|
@ -15,6 +15,8 @@ import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
/**
|
||||
@ -260,12 +262,9 @@ public abstract class Addresses {
|
||||
}
|
||||
if (rv == null) {
|
||||
try {
|
||||
boolean isIPv4 = host.replaceAll("[0-9\\.]", "").length() == 0;
|
||||
if (isIPv4 && host.replaceAll("[0-9]", "").length() != 3)
|
||||
return null;
|
||||
rv = InetAddress.getByName(host).getAddress();
|
||||
if (isIPv4 ||
|
||||
host.replaceAll("[0-9a-fA-F:]", "").length() == 0) {
|
||||
if (InetAddressUtils.isIPv4Address(host) ||
|
||||
InetAddressUtils.isIPv6Address(host)) {
|
||||
synchronized (_IPAddress) {
|
||||
_IPAddress.put(host, rv);
|
||||
}
|
||||
|
@ -755,6 +755,8 @@ public class EepGet {
|
||||
Thread pusher = null;
|
||||
_decompressException = null;
|
||||
if (_isGzippedResponse) {
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Gzipped response, starting decompressor");
|
||||
PipedInputStream pi = BigPipedInputStream.getInstance();
|
||||
PipedOutputStream po = new PipedOutputStream(pi);
|
||||
pusher = new I2PAppThread(new Gunzipper(pi, _out), "EepGet Decompressor");
|
||||
@ -1096,7 +1098,7 @@ public class EepGet {
|
||||
*/
|
||||
private int handleStatus(String line) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Status line: [" + line + "]");
|
||||
_log.debug("Status line: [" + line.trim() + "]");
|
||||
String[] toks = line.split(" ", 3);
|
||||
if (toks.length < 2) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
@ -1160,17 +1162,13 @@ public class EepGet {
|
||||
lookahead[1] = lookahead[2];
|
||||
lookahead[2] = (byte)cur;
|
||||
}
|
||||
|
||||
private static boolean isEndOfHeaders(byte lookahead[]) {
|
||||
byte first = lookahead[0];
|
||||
byte second = lookahead[1];
|
||||
byte third = lookahead[2];
|
||||
return (isNL(second) && isNL(third)) || // \n\n
|
||||
(isNL(first) && isNL(third)); // \n\r\n
|
||||
return lookahead[2] == NL &&
|
||||
(lookahead[0] == NL || lookahead[1] == NL); // \n\n or \n\r\n
|
||||
}
|
||||
|
||||
/** we ignore any potential \r, since we trim it on write anyway */
|
||||
private static final byte NL = '\n';
|
||||
private static boolean isNL(byte b) { return (b == NL); }
|
||||
|
||||
/**
|
||||
* @param timeout may be null
|
||||
@ -1315,7 +1313,8 @@ public class EepGet {
|
||||
buf.append("Content-length: ").append(_postData.length()).append("\r\n");
|
||||
// This will be replaced if we are going through I2PTunnelHTTPClient
|
||||
buf.append("Accept-Encoding: ");
|
||||
if ((!_shouldProxy) &&
|
||||
// as of 0.9.23, the proxy passes the Accept-Encoding header through
|
||||
if ( /* (!_shouldProxy) && */
|
||||
// This is kindof a hack, but if we are downloading a gzip file
|
||||
// we don't want to transparently gunzip it and save it as a .gz file.
|
||||
(!path.endsWith(".gz")) && (!path.endsWith(".tgz")))
|
||||
|
@ -284,7 +284,7 @@ public class I2PSSLSocketFactory {
|
||||
host.equals("localhost") ||
|
||||
host.equals("127.0.0.1") ||
|
||||
host.equals("::1") ||
|
||||
host.equals("0:0:0:0:0:0:0::1")) {
|
||||
host.equals("0:0:0:0:0:0:0:1")) {
|
||||
if (log.shouldWarn())
|
||||
log.warn("Skipping hostname validation for " + host);
|
||||
return;
|
||||
|
@ -10,6 +10,7 @@ package net.i2p.util;
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Flushable;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
@ -37,7 +38,7 @@ import net.i2p.data.DataHelper;
|
||||
* writes them where appropriate.
|
||||
*
|
||||
*/
|
||||
public class LogManager {
|
||||
public class LogManager implements Flushable {
|
||||
public final static String CONFIG_LOCATION_PROP = "loggerConfigLocation";
|
||||
public final static String FILENAME_OVERRIDE_PROP = "loggerFilenameOverride";
|
||||
public final static String CONFIG_LOCATION_DEFAULT = "logger.config";
|
||||
|
@ -67,10 +67,12 @@ abstract class LogWriterBase implements Runnable {
|
||||
|
||||
public void run() {
|
||||
_write = true;
|
||||
// don't bother on Android
|
||||
final boolean shouldReadConfig = !SystemVersion.isAndroid();
|
||||
try {
|
||||
while (_write) {
|
||||
flushRecords();
|
||||
if (_write)
|
||||
if (_write && shouldReadConfig)
|
||||
rereadConfig();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -145,7 +147,7 @@ abstract class LogWriterBase implements Runnable {
|
||||
private String dupMessage(int dupCount, LogRecord lastRecord, boolean reverse) {
|
||||
String arrows = reverse ? "↓↓↓" : "^^^";
|
||||
return LogRecordFormatter.getWhen(_manager, lastRecord) + ' ' + arrows + ' ' +
|
||||
_(dupCount, "1 similar message omitted", "{0} similar messages omitted") + ' ' + arrows + '\n';
|
||||
_t(dupCount, "1 similar message omitted", "{0} similar messages omitted") + ' ' + arrows + '\n';
|
||||
}
|
||||
|
||||
private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
|
||||
@ -154,7 +156,7 @@ abstract class LogWriterBase implements Runnable {
|
||||
* gettext
|
||||
* @since 0.9.3
|
||||
*/
|
||||
private String _(int a, String b, String c) {
|
||||
private String _t(int a, String b, String c) {
|
||||
return Translate.getString(a, b, c, _manager.getContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,8 @@ public class PortMapper {
|
||||
public static final String SVC_BOB = "BOB";
|
||||
/** not necessary, already in config? */
|
||||
public static final String SVC_I2CP = "I2CP";
|
||||
/** @since 0.9.23 */
|
||||
public static final String SVC_I2CP_SSL = "I2CP-SSL";
|
||||
|
||||
/**
|
||||
* @param context unused for now
|
||||
|
@ -6,6 +6,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
@ -38,7 +39,7 @@ public class SimpleTimer2 {
|
||||
private static final int MAX_THREADS = 4;
|
||||
private final ScheduledThreadPoolExecutor _executor;
|
||||
private final String _name;
|
||||
private volatile int _count;
|
||||
private final AtomicInteger _count = new AtomicInteger();
|
||||
private final int _threads;
|
||||
|
||||
/**
|
||||
@ -102,7 +103,7 @@ public class SimpleTimer2 {
|
||||
super.afterExecute(r, t);
|
||||
if (t != null) { // shoudn't happen, caught in RunnableEvent.run()
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(SimpleTimer2.class);
|
||||
log.log(Log.CRIT, "wtf, event borked: " + r, t);
|
||||
log.log(Log.CRIT, "event borked: " + r, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -110,7 +111,7 @@ public class SimpleTimer2 {
|
||||
private class CustomThreadFactory implements ThreadFactory {
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread rv = Executors.defaultThreadFactory().newThread(r);
|
||||
rv.setName(_name + ' ' + (++_count) + '/' + _threads);
|
||||
rv.setName(_name + ' ' + _count.incrementAndGet() + '/' + _threads);
|
||||
// Uncomment this to test threadgrouping, but we should be all safe now that the constructor preallocates!
|
||||
// String name = rv.getThreadGroup().getName();
|
||||
// if(!name.equals("main")) {
|
||||
@ -164,7 +165,8 @@ public class SimpleTimer2 {
|
||||
* New code should use SimpleTimer2.TimedEvent.
|
||||
*
|
||||
* @since 0.9.20
|
||||
* @param timeoutMs run first and subsequent iterations of this event every timeoutMs ms
|
||||
* @param timeoutMs run subsequent iterations of this event every timeoutMs ms, 5000 minimum
|
||||
* @throws IllegalArgumentException if timeoutMs less than 5000
|
||||
*/
|
||||
public void addPeriodicEvent(final SimpleTimer.TimedEvent event, final long timeoutMs) {
|
||||
addPeriodicEvent(event, timeoutMs, timeoutMs);
|
||||
@ -183,7 +185,8 @@ public class SimpleTimer2 {
|
||||
*
|
||||
* @since 0.9.20
|
||||
* @param delay run the first iteration of this event after delay ms
|
||||
* @param timeoutMs run subsequent iterations of this event every timeoutMs ms
|
||||
* @param timeoutMs run subsequent iterations of this event every timeoutMs ms, 5000 minimum
|
||||
* @throws IllegalArgumentException if timeoutMs less than 5000
|
||||
*/
|
||||
public void addPeriodicEvent(final SimpleTimer.TimedEvent event, final long delay, final long timeoutMs) {
|
||||
|
||||
@ -254,6 +257,8 @@ public class SimpleTimer2 {
|
||||
private long _nextRun;
|
||||
/** whether this was scheduled during RUNNING state. LOCKING: this */
|
||||
private boolean _rescheduleAfterRun;
|
||||
/** whether this was cancelled during RUNNING state. LOCKING: this */
|
||||
private boolean _cancelAfterRun;
|
||||
|
||||
/** must call schedule() later */
|
||||
public TimedEvent(SimpleTimer2 pool) {
|
||||
@ -286,12 +291,17 @@ public class SimpleTimer2 {
|
||||
public synchronized void schedule(long timeoutMs) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Scheduling: " + this + " timeout = " + timeoutMs + " state: " + _state);
|
||||
if (timeoutMs <= 0 && _log.shouldLog(Log.WARN))
|
||||
if (timeoutMs <= 0) {
|
||||
// streaming timers do call with timeoutMs == 0
|
||||
if (timeoutMs < 0 && _log.shouldLog(Log.WARN))
|
||||
_log.warn("Timeout <= 0: " + this + " timeout = " + timeoutMs + " state: " + _state);
|
||||
timeoutMs = 1; // otherwise we may execute before _future is updated, which is fine
|
||||
// except it triggers 'early execution' warning logging
|
||||
}
|
||||
|
||||
// always set absolute time of execution
|
||||
_nextRun = timeoutMs + System.currentTimeMillis();
|
||||
_cancelAfterRun = false;
|
||||
|
||||
switch(_state) {
|
||||
case RUNNING:
|
||||
@ -352,11 +362,13 @@ public class SimpleTimer2 {
|
||||
* @param timeoutMs
|
||||
*/
|
||||
public synchronized void forceReschedule(long timeoutMs) {
|
||||
cancel();
|
||||
// don't cancel while running!
|
||||
if (_state == TimedEventState.SCHEDULED)
|
||||
cancel();
|
||||
schedule(timeoutMs);
|
||||
}
|
||||
|
||||
/** returns true if cancelled */
|
||||
/** @return true if cancelled */
|
||||
public synchronized boolean cancel() {
|
||||
// always clear
|
||||
_rescheduleAfterRun = false;
|
||||
@ -365,7 +377,9 @@ public class SimpleTimer2 {
|
||||
case CANCELLED: // fall through
|
||||
case IDLE:
|
||||
break; // my preference is to throw IllegalState here, but let it be.
|
||||
case RUNNING: // fall through
|
||||
case RUNNING:
|
||||
_cancelAfterRun = true;
|
||||
return true;
|
||||
case SCHEDULED:
|
||||
boolean cancelled = _future.cancel(false);
|
||||
if (cancelled)
|
||||
@ -378,20 +392,29 @@ public class SimpleTimer2 {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
run2();
|
||||
} catch (RuntimeException re) {
|
||||
_log.error("timer error", re);
|
||||
throw re;
|
||||
}
|
||||
}
|
||||
|
||||
private void run2() {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Running: " + this);
|
||||
long before = System.currentTimeMillis();
|
||||
long delay = 0;
|
||||
synchronized(this) {
|
||||
if (_rescheduleAfterRun)
|
||||
throw new IllegalStateException("rescheduleAfterRun cannot be true here");
|
||||
throw new IllegalStateException(this + " rescheduleAfterRun cannot be true here");
|
||||
|
||||
switch(_state) {
|
||||
case CANCELLED:
|
||||
return; // goodbye
|
||||
case IDLE: // fall through
|
||||
case RUNNING:
|
||||
throw new IllegalStateException("not possible to be in " + _state);
|
||||
throw new IllegalStateException(this + " not possible to be in " + _state);
|
||||
case SCHEDULED: // proceed, switch to IDLE in case I need to reschedule
|
||||
_state = TimedEventState.IDLE;
|
||||
}
|
||||
@ -411,12 +434,12 @@ public class SimpleTimer2 {
|
||||
if (_future != null)
|
||||
delay = _future.getDelay(TimeUnit.MILLISECONDS);
|
||||
else if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(_pool + " wtf, no _future " + this);
|
||||
_log.warn(_pool + " no _future " + this);
|
||||
// This can be an incorrect warning especially after a schedule(0)
|
||||
if (_log.shouldLog(Log.WARN) && delay > 100)
|
||||
_log.warn(_pool + " wtf, early execution " + delay + ": " + this);
|
||||
_log.warn(_pool + " early execution " + delay + ": " + this);
|
||||
else if (_log.shouldLog(Log.WARN) && delay < -1000)
|
||||
_log.warn(" wtf, late execution " + (0 - delay) + ": " + this + _pool.debug());
|
||||
_log.warn(" late execution " + (0 - delay) + ": " + this + _pool.debug());
|
||||
try {
|
||||
timeReached();
|
||||
} catch (Throwable t) {
|
||||
@ -426,22 +449,27 @@ public class SimpleTimer2 {
|
||||
switch(_state) {
|
||||
case SCHEDULED: // fall through
|
||||
case IDLE:
|
||||
throw new IllegalStateException("can't be " + _state);
|
||||
throw new IllegalStateException(this + " can't be " + _state);
|
||||
case CANCELLED:
|
||||
break; // nothing
|
||||
case RUNNING:
|
||||
_state = TimedEventState.IDLE;
|
||||
// do we need to reschedule?
|
||||
if (_rescheduleAfterRun) {
|
||||
_rescheduleAfterRun = false;
|
||||
schedule(_nextRun - System.currentTimeMillis());
|
||||
if (_cancelAfterRun) {
|
||||
_cancelAfterRun = false;
|
||||
_state = TimedEventState.CANCELLED;
|
||||
} else {
|
||||
_state = TimedEventState.IDLE;
|
||||
// do we need to reschedule?
|
||||
if (_rescheduleAfterRun) {
|
||||
_rescheduleAfterRun = false;
|
||||
schedule(_nextRun - System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
long time = System.currentTimeMillis() - before;
|
||||
if (time > 500 && _log.shouldLog(Log.WARN))
|
||||
_log.warn(_pool + " wtf, event execution took " + time + ": " + this);
|
||||
_log.warn(_pool + " event execution took " + time + ": " + this);
|
||||
if (_log.shouldLog(Log.INFO)) {
|
||||
// this call is slow - iterates through a HashMap -
|
||||
// would be better to have a local AtomicLong if we care
|
||||
@ -470,6 +498,7 @@ public class SimpleTimer2 {
|
||||
return _executor.getCompletedTaskCount();
|
||||
}
|
||||
|
||||
/** warning - slow */
|
||||
private String debug() {
|
||||
_executor.purge(); // Remove cancelled tasks from the queue so we get a good queue size stat
|
||||
return
|
||||
@ -490,10 +519,13 @@ public class SimpleTimer2 {
|
||||
* Schedule periodic event
|
||||
*
|
||||
* @param delay run the first iteration of this event after delay ms
|
||||
* @param timeoutMs run subsequent iterations of this event every timeoutMs ms
|
||||
* @param timeoutMs run subsequent iterations of this event every timeoutMs ms, 5000 minimum
|
||||
* @throws IllegalArgumentException if timeoutMs less than 5000
|
||||
*/
|
||||
public PeriodicTimedEvent(SimpleTimer2 pool, long delay, long timeoutMs) {
|
||||
super(pool, delay);
|
||||
if (timeoutMs < 5000)
|
||||
throw new IllegalArgumentException("timeout minimum 5000");
|
||||
_timeoutMs = timeoutMs;
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public abstract class Translate {
|
||||
* The {0} will be replaced by the parameter.
|
||||
* Single quotes must be doubled, i.e. ' -> '' in the string.
|
||||
* @param o parameter, not translated.
|
||||
* To tranlslate parameter also, use _("foo {0} bar", _("baz"))
|
||||
* To tranlslate parameter also, use _t("foo {0} bar", _t("baz"))
|
||||
* Do not double the single quotes in the parameter.
|
||||
* Use autoboxing to call with ints, longs, floats, etc.
|
||||
*/
|
||||
|
@ -351,7 +351,7 @@ public class TranslateReader extends FilterReader {
|
||||
public void tag(List<String> args) {
|
||||
if (args.size() <= 0)
|
||||
return;
|
||||
_out.print("\t_(");
|
||||
_out.print("\t_t(");
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
if (i > 0)
|
||||
_out.print(", ");
|
||||
@ -373,6 +373,9 @@ public class TranslateReader extends FilterReader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not comment out, used to extract tags as a part of the build process.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
if (args.length >= 2 && args[0].equals("test"))
|
||||
|
@ -28,9 +28,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.metanotion.io;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface RandomAccessInterface {
|
||||
public interface RandomAccessInterface extends Closeable {
|
||||
public long getFilePointer() throws IOException;
|
||||
public long length() throws IOException;
|
||||
public int read() throws IOException;
|
||||
|
@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.metanotion.io.block;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
@ -64,7 +65,7 @@ import net.i2p.util.Log;
|
||||
* Pages are 1 KB and are numbered starting from 1.
|
||||
* e.g. the Metaindex skiplist is at offset 1024 bytes
|
||||
*/
|
||||
public class BlockFile {
|
||||
public class BlockFile implements Closeable {
|
||||
public static final int PAGESIZE = 1024;
|
||||
public static final long OFFSET_MOUNTED = 20;
|
||||
public final Log log = I2PAppContext.getGlobalContext().logManager().getLog(BlockFile.class);
|
||||
|
@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.metanotion.io.block.index;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
@ -50,7 +51,7 @@ import net.i2p.util.Log;
|
||||
*
|
||||
* Always fits on one page.
|
||||
*/
|
||||
public class BSkipList extends SkipList {
|
||||
public class BSkipList extends SkipList implements Closeable {
|
||||
private static final long MAGIC = 0x536b69704c697374l; // "SkipList"
|
||||
public int firstSpanPage = 0;
|
||||
public int firstLevelPage = 0;
|
||||
|
@ -28,12 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.metanotion.util.skiplist;
|
||||
|
||||
import java.io.Flushable;
|
||||
|
||||
import net.metanotion.io.block.BlockFile;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class SkipLevels {
|
||||
public class SkipLevels implements Flushable {
|
||||
/** We can't have more than 2**32 pages */
|
||||
public static final int MAX_SIZE = 32;
|
||||
|
||||
|
@ -28,13 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.metanotion.util.skiplist;
|
||||
|
||||
import java.io.Flushable;
|
||||
import java.util.Random;
|
||||
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
//import net.metanotion.io.block.BlockFile;
|
||||
|
||||
public class SkipList {
|
||||
public class SkipList implements Flushable {
|
||||
/** the probability of each next higher level */
|
||||
protected static final int P = 2;
|
||||
private static final int MIN_SLOTS = 4;
|
||||
|
@ -28,9 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.metanotion.util.skiplist;
|
||||
|
||||
import java.io.Flushable;
|
||||
|
||||
//import net.metanotion.io.block.BlockFile;
|
||||
|
||||
public class SkipSpan {
|
||||
public class SkipSpan implements Flushable {
|
||||
/** This is actually limited by BlockFile.spanSize which is much smaller */
|
||||
public static final int MAX_SIZE = 256;
|
||||
|
||||
|
Reference in New Issue
Block a user